202 Commits

Author SHA1 Message Date
280a8123ec updated README.md
Some checks reported errors
BlockStorage/repertory/pipeline/pr-master Something is wrong with the build of this commit
BlockStorage/repertory/pipeline/head This commit looks good
2025-02-10 14:07:46 -06:00
f3081f3930 updated build system 2025-02-10 12:50:46 -06:00
b7d2ac3304 fix
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-25 09:36:33 -06:00
26358b1e67 unit tests and fixes
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-25 06:20:50 -06:00
feeef3a044 added unit tests 2025-01-25 06:13:07 -06:00
e013cbbdbb updated CHANGELOG.md
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2025-01-25 06:01:57 -06:00
7c8b44bf69 removed debug logs 2025-01-25 06:01:00 -06:00
f7b829f71c fix check deleted 2025-01-25 05:59:44 -06:00
412e03898d fix externally removed file
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
2025-01-25 05:26:19 -06:00
c1c5c3f0f1 fixes
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-24 19:35:25 -06:00
47f5b82b4e refactor
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-24 13:30:25 -06:00
ebee5ec857 refactor 2025-01-24 13:29:38 -06:00
bfe7b8915d refactor 2025-01-24 12:50:16 -06:00
8547fb7d43 refactor 2025-01-24 12:24:53 -06:00
4f2ff33226 refactor 2025-01-24 10:18:03 -06:00
600b658109 refactor event system 2025-01-24 10:16:00 -06:00
374eb67f6b refactor event system 2025-01-24 10:14:47 -06:00
7848dcebe4 refactor event system 2025-01-24 10:14:05 -06:00
a34443ed94 refactor event system 2025-01-24 09:44:28 -06:00
ff985e724d refactor 2025-01-24 09:42:15 -06:00
1ee478ca71 refactor 2025-01-24 09:40:02 -06:00
807a6e90f8 refactor event system 2025-01-24 09:38:43 -06:00
694d4d4662 refactor event system 2025-01-24 09:35:47 -06:00
ebdc4877a8 refactor event system 2025-01-24 08:32:00 -06:00
993356dec6 refactor event system 2025-01-24 08:26:13 -06:00
dea69815ef refactor event system 2025-01-24 08:24:03 -06:00
5da7b6a51a refactor event system 2025-01-24 08:19:18 -06:00
ad5a1cd5ff refactor event system 2025-01-24 08:10:33 -06:00
33e9208190 refactor event system 2025-01-24 08:02:41 -06:00
3d25364540 refactor event system 2025-01-24 07:52:58 -06:00
b00d219f34 refactor event system 2025-01-24 07:36:23 -06:00
f1a0b6add1 refactor event system 2025-01-24 06:52:45 -06:00
3b4767290b refactor event system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 19:35:48 -06:00
eb26f59059 refactor event system
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2025-01-23 19:34:43 -06:00
efcb319d8c refactor event system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 19:32:40 -06:00
52e7f675fc refactor event system 2025-01-23 19:28:55 -06:00
78e9c95054 disable header
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 19:22:02 -06:00
8fa3ccf97c refactor event system
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2025-01-23 19:21:20 -06:00
1311d665b5 refactor event system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 19:19:53 -06:00
62e45894b8 refactor event system
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2025-01-23 19:18:59 -06:00
094aec0afb refactor event system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 19:15:36 -06:00
3b46a48078 refactor event system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 19:14:17 -06:00
8c53a07d64 refactor event system 2025-01-23 19:12:15 -06:00
03485935b7 refactor event system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 19:10:06 -06:00
4b3582cbb0 refactor event system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 19:06:57 -06:00
8272ec2f8a refactor event system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-23 15:19:37 -06:00
7309ca477a refactor event system 2025-01-23 14:58:24 -06:00
e8ef11cef4 refactor event system 2025-01-23 14:54:59 -06:00
80b77daa8a refactor event system 2025-01-23 11:13:00 -06:00
cb75efd96f refactor event system 2025-01-23 11:12:19 -06:00
631a1bc914 refactor event system 2025-01-23 11:10:47 -06:00
5064ec3f9a refactor event system 2025-01-23 10:56:20 -06:00
7c072f98dd refactor event system 2025-01-23 09:41:32 -06:00
d732bfb224 refactor event system 2025-01-23 09:38:15 -06:00
4241adb4d3 refactor event system 2025-01-23 09:37:45 -06:00
e1c35624f6 fix
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-22 20:28:27 -06:00
9b75618fb3 updated build system
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
2025-01-22 20:18:25 -06:00
6464c01d8b updated CHANGELOG.md
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-22 14:44:36 -06:00
58db36d628 updated CHANGELOG.md 2025-01-22 13:39:40 -06:00
f39c6550f2 refactor 2025-01-22 13:37:48 -06:00
400c97cebd refactor 2025-01-22 13:29:08 -06:00
a2ad258b7c refactor 2025-01-22 13:23:52 -06:00
c4b4fe83fb refactor 2025-01-22 13:21:44 -06:00
262fccf9a6 refactor 2025-01-22 13:21:31 -06:00
50898488f0 refactor 2025-01-22 13:13:36 -06:00
1acb3311b1 refactor 2025-01-22 13:12:18 -06:00
3fd3f85cc9 refactor 2025-01-22 13:07:10 -06:00
cbbd586347 refactor 2025-01-22 13:01:36 -06:00
57a591c51e refactor 2025-01-22 12:58:02 -06:00
29fb395758 revert change 2025-01-22 12:47:24 -06:00
b3f87e2828 refactor 2025-01-22 12:42:00 -06:00
7e06f810ea refactor 2025-01-22 12:41:28 -06:00
02e568b77a fix memory leak 2025-01-22 12:37:00 -06:00
8b2bafc9f3 refactor 2025-01-22 08:47:56 -06:00
97e5f17049 refactor 2025-01-22 08:06:54 -06:00
124dc62250 refactor 2025-01-22 08:05:35 -06:00
5da4d4e940 refactor 2025-01-22 08:01:35 -06:00
b507643d23 limit directory cache to directory operations 2025-01-22 07:39:41 -06:00
1e25fb57f1 refactor 2025-01-22 07:31:02 -06:00
4d8e59f97f refactor 2025-01-22 07:24:25 -06:00
881778e485 refactor events 2025-01-22 07:14:21 -06:00
3efb2b817f refactor 2025-01-21 15:24:39 -06:00
21d02534e5 refactor system stop 2025-01-21 15:19:33 -06:00
1b11e500f3 refactor winfsp system stop 2025-01-21 15:05:04 -06:00
f57bbdbb50 refactor 2025-01-21 14:59:11 -06:00
1c65f51ef4 refactor system stop 2025-01-21 14:57:13 -06:00
f44bb6bcfc force stop 2025-01-21 14:52:51 -06:00
57d9884510 refactor 2025-01-21 13:46:51 -06:00
5da036e979 refactor system stop 2025-01-21 13:29:56 -06:00
daa8b9df24 refactor system stop 2025-01-21 13:18:22 -06:00
fe2a1b96b2 rocksdb cache adjustments 2025-01-21 09:23:43 -06:00
be678e8f9c refactor 2025-01-21 08:01:15 -06:00
b5ae3e4ed1 updated CHANGELOG.md
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-16 19:52:51 -06:00
89a2d5866a updated CHANGELOG.md
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2025-01-16 19:48:33 -06:00
5264d17ae8 remote fixes
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-16 19:45:41 -06:00
1718464c60 updated build system
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-05 20:12:02 -06:00
85756ddd8c updated build system
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
2025-01-05 20:06:09 -06:00
e8240948b7 updated build system
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
2025-01-05 20:01:45 -06:00
77088e6608 updated build system
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-05 14:55:44 -06:00
ddbebef850 updated build system
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2025-01-04 15:22:49 -06:00
7cf636b8ed updated build system
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-02 20:30:25 -06:00
754dfc49db updated build system
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2025-01-02 20:28:51 -06:00
63b2d0e741 updated build system
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-02 20:19:27 -06:00
96ac72ae21 fix comment
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-02 17:39:48 -06:00
0bbf6b5942 refactor
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-02 14:24:58 -06:00
74ef36956d re-enable cleanup 2025-01-02 14:22:40 -06:00
bbe065819c refactor 2025-01-02 14:22:17 -06:00
3493054f1a handle remove error 2025-01-02 14:20:20 -06:00
743281497c refactor 2025-01-02 14:14:21 -06:00
eaa6a6f92e refactor cleanup 2025-01-02 14:01:16 -06:00
a25dd8178e refactor cleanup 2025-01-02 13:43:22 -06:00
71463bfee4 refactor 2025-01-02 12:07:01 -06:00
270df62dbe refactor 2025-01-02 12:01:45 -06:00
5bd7ded7d9 refactor 2025-01-02 11:59:01 -06:00
b5048a422f refactor 2025-01-02 11:56:12 -06:00
c27528fe73 begin working on better handling of removed files 2025-01-02 10:27:52 -06:00
c3978562d5 cleanup 2025-01-02 08:59:19 -06:00
637892cff1 refactor 2025-01-02 08:58:02 -06:00
998a3d9d83 updated test 2025-01-02 08:50:44 -06:00
8ed8822625 refactor 2025-01-02 08:38:43 -06:00
196abaebcc refactor 2025-01-02 08:36:55 -06:00
653e8000ff refactor 2025-01-02 08:34:51 -06:00
ea362211aa fix 2025-01-02 08:32:42 -06:00
a4a9d069d3 fix 2025-01-02 08:27:45 -06:00
9cb7f9accf updated CHANGELOG.md 2025-01-02 08:19:42 -06:00
4e5454efb5 always use direct for read-only providers 2025-01-02 08:19:10 -06:00
a8c3f31298 refactor 2025-01-02 07:59:07 -06:00
f3093c27cd refactor 2025-01-02 07:57:07 -06:00
4526a9d860 refactor 2025-01-02 07:50:58 -06:00
a1ada5aa8c refactor 2025-01-02 07:48:56 -06:00
1ae8b8b793 refactor 2025-01-02 07:45:08 -06:00
f44cc99a82 refactor 2025-01-02 07:08:12 -06:00
75657bec58 fix
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-01 01:35:45 -06:00
4fef036f10 refactor
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2025-01-01 01:19:59 -06:00
ecb9783f4e refactor 2025-01-01 01:15:11 -06:00
bdf85908ca updated CHANGELOG.md
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2024-12-31 17:30:20 -06:00
9cb3cdabb0 cleanup
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2024-12-31 14:49:26 -06:00
6cf082dfa7 refactor 2024-12-31 14:45:52 -06:00
1a140d4dfd refactor 2024-12-31 14:45:11 -06:00
1cc8571a04 refactor 2024-12-31 14:42:57 -06:00
cf8c631938 refactor 2024-12-31 14:42:24 -06:00
4cba2a16f9 updated CHANGELOG.md 2024-12-31 14:29:55 -06:00
7c5f074d5a [bug] Address slow directory responses in S3 mounts for deep nested directories #28 2024-12-31 14:22:55 -06:00
a251cf6abf exception handling 2024-12-31 13:42:50 -06:00
31f7a47889 exception handling 2024-12-31 13:41:38 -06:00
23de2af98d exception handling 2024-12-31 13:41:00 -06:00
2446f024ef exception handling 2024-12-31 13:39:29 -06:00
45ddd528b2 exception handling 2024-12-31 13:37:55 -06:00
36908f7da9 [bug] Sia provider error responses are not being logged #30 2024-12-31 13:34:08 -06:00
1a11d55782 updated CHANGELOG.md 2024-12-31 13:20:50 -06:00
e344eddbcb [bug] Sia provider error responses are not being logged #30 2024-12-31 13:19:42 -06:00
09da7a29a9 [bug] Sia provider error responses are not being logged #30 2024-12-31 13:13:17 -06:00
5b5ac0937c [bug] Sia provider error responses are not being logged #30 2024-12-31 13:12:49 -06:00
c69818fed6 [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 12:56:13 -06:00
81712e7a99 [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 12:55:52 -06:00
75d2d39e7c refactor 2024-12-31 12:53:08 -06:00
ccc4a30ad5 spelling 2024-12-31 11:35:27 -06:00
a9bb12015a fix missing request headers 2024-12-31 11:32:47 -06:00
474f90ee33 fix missing request headers 2024-12-31 11:31:03 -06:00
ae7d5fe284 fix missing request headers 2024-12-31 11:29:05 -06:00
bf700b9d59 [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 11:05:20 -06:00
0d4b3f5e7e [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 10:55:33 -06:00
67076458f0 updated CHANGELOG.md 2024-12-31 10:28:57 -06:00
a8479eefd1 [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 10:22:49 -06:00
e1eda99a72 [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 10:15:21 -06:00
ed4a4f0742 [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 10:14:13 -06:00
84e89d3b83 [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 09:50:20 -06:00
5e3efde376 [bug] S3 provider should limit max key size to 1024 #31 2024-12-31 09:39:20 -06:00
f28e17f3e5 updated CHANGELOG.md 2024-12-31 08:53:55 -06:00
699ecafc22 updated CHANGELOG.md 2024-12-31 08:53:00 -06:00
247cc301ea [bug] S3 error responses are not being logged #29 2024-12-31 08:47:28 -06:00
bc43338127 [bug] S3 error responses are not being logged #29 2024-12-31 08:46:17 -06:00
4e86f2a7de refactor 2024-12-31 08:42:22 -06:00
b9fe2746e3 refactor 2024-12-31 08:31:36 -06:00
4fe9d09f0a updated CHANGELOG.md
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2024-12-30 19:37:41 -06:00
777db300e1 fix
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2024-12-30 18:44:21 -06:00
62a303e856 [bug] Address slow directory responses in S3 mounts for deep nested directories #28
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
[bug] S3 error responses are not being logged #29
2024-12-30 12:09:52 -06:00
ae573af89d updated CHANGELOG.md
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2024-12-29 17:49:12 -06:00
0c41a3309e fix invalid error
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2024-12-29 17:43:09 -06:00
4cb3e22308 moved event to debug
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2024-12-29 14:44:19 -06:00
9d7d36922f updated build system
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2024-12-29 12:18:01 -06:00
3190c5f133 updated build system
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...
2024-12-29 12:04:17 -06:00
5fadb796d1 fix CHANGELOG.md
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
2024-12-29 09:57:29 -06:00
4a213e5ca5 updated CHANGELOG.md 2024-12-29 09:57:14 -06:00
9fea962563 updated CHANGELOG.md 2024-12-29 09:43:54 -06:00
ac6c333df3 updated CHANGELOG.md 2024-12-29 09:41:37 -06:00
4bbff47b6f updated build system 2024-12-29 09:21:56 -06:00
f01daa4296 [Unit Test] Complete FUSE unit tests #22
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2024-12-29 07:09:49 -06:00
96c2f8ee1e [Unit Test] Complete FUSE unit tests #22 2024-12-29 07:08:25 -06:00
9eb3e7a22d [Unit Test] Complete FUSE unit tests #22 2024-12-29 07:06:19 -06:00
3c2c783683 [Unit Test] Complete FUSE unit tests #22 2024-12-29 06:41:55 -06:00
2e24f9bb44 updated build system
All checks were successful
BlockStorage/repertory/pipeline/head This commit looks good
2024-12-28 22:23:27 -06:00
6bb3351cb8 fix deliver script
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
2024-12-28 22:08:24 -06:00
6086a0ea12 cleanup 2024-12-28 19:36:25 -06:00
b4b688d3b9 refactor 2024-12-28 19:35:17 -06:00
43bf3c0cb2 refactor 2024-12-28 19:33:42 -06:00
26897c256b call shutdown before close 2024-12-28 19:31:02 -06:00
a788563db6 cleanup 2024-12-28 19:27:36 -06:00
9fb1c747a6 updated CHANGELOG.md
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2024-12-28 16:30:32 -06:00
5982978879 updated CHANGELOG.md
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit
2024-12-28 16:25:22 -06:00
5ca4584416 updated copyright 2024-12-28 16:20:41 -06:00
3eca1af971 updated version 2024-12-28 16:04:38 -06:00
50 changed files with 1264 additions and 2224 deletions

View File

@ -128,7 +128,6 @@ libcurl
libdsm libdsm
libevent libevent
libexample libexample
libexpat
libfuse3 libfuse3
libgmock libgmock
libgtest libgtest
@ -192,7 +191,6 @@ secp256k1
secur32 secur32
sfml_project sfml_project
shlwapi shlwapi
skynet
source_subdir source_subdir
spdlog spdlog
spdlog_project spdlog_project

View File

@ -1,36 +1,13 @@
# Changelog # Changelog
## v2.0.4-rc
### BREAKING CHANGES
* `renterd` v2.0.0+ is now required. Prior versions will fail to mount.
### Issues
* \#35 [bug] Low frequency check is set to '0' instead of 1 hour by default
* \#36 [bug] Max cache size bytes is set to '0' by default
### Changes from v2.0.3-rc
* Added Sia API version check prior to mounting
* Added back `-cv` (check version) CLI option
* Continue documentation updates
* Fixed setting `ApiAuth` via `set_value_by_name`
* Fixed setting `HostConfig.ApiUser` via `set_value_by_name`
* Fixed setting `HostConfig.Path` via `set_value_by_name`
* Fixed setting `HostConfig.Protocol` via `set_value_by_name`
* Improved ring buffer read-ahead
* Integrated `renterd` version 2.0.0
* Prefer using local cache file when opening files
* Refactored `app_config` unit tests
* Refactored polling to be more accurate on scheduling tasks
## v2.0.3-rc ## v2.0.3-rc
<!-- markdownlint-disable-next-line -->
### Issues ### Issues
* ~~\#12 \[Unit Test\] Complete all providers unit tests~~
* ~~\#20 Add support to evict open files~~
* ~~\#21 \[Unit Test \] Complete WinFSP unit tests~~
* ~~\#22 \[Unit Test\] Complete FUSE unit tests~~
* \#28 \[bug\] Address slow directory responses in S3 mounts for deeply nested directories * \#28 \[bug\] Address slow directory responses in S3 mounts for deeply nested directories
* \#29 \[bug\] S3 error responses are not being logged * \#29 \[bug\] S3 error responses are not being logged
* \#30 \[bug\] Sia provider error responses are not logged * \#30 \[bug\] Sia provider error responses are not logged

View File

@ -58,10 +58,6 @@ if(PROJECT_IS_MINGW)
endif() endif()
endif() endif()
if (PROJECT_ENABLE_V2_ERRORS)
add_definitions(-DPROJECT_ENABLE_V2_ERRORS)
endif()
include(cmake/settings.cmake) include(cmake/settings.cmake)
include(cmake/flags.cmake) include(cmake/flags.cmake)
@ -147,7 +143,6 @@ endif()
-DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT} -DPROJECT_COPYRIGHT=${PROJECT_COPYRIGHT}
-DPROJECT_DESC=${PROJECT_DESC} -DPROJECT_DESC=${PROJECT_DESC}
-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR} -DPROJECT_DIST_DIR=${PROJECT_DIST_DIR}
-DPROJECT_ENABLE_V2_ERRORS=${PROJECT_ENABLE_V2_ERRORS}
-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES} -DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES}
-DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST} -DPROJECT_ENABLE_BOOST=${PROJECT_ENABLE_BOOST}
-DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB} -DPROJECT_ENABLE_CPP_HTTPLIB=${PROJECT_ENABLE_CPP_HTTPLIB}

135
README.md
View File

@ -1,22 +1,23 @@
# Repertory # Repertory
Repertory allows you to mount S3 and Sia via FUSE on Linux or via WinFSP Repertory allows you to mount AWS S3 and Sia via FUSE on Linux ~~/OS X~~ or via WinFSP
on Windows. on Windows.
## Details and Features ## Details and Features
* Optimized for [Plex Media Server](https://www.plex.tv/) * Optimized for [Plex Media Server](https://www.plex.tv/)
* Single application to mount S3 and/or Sia * Single application to mount AWS S3 and/or Sia
* Remote mounting of Repertory instances on Linux and Windows * Remote mounting of Repertory instances on Linux ~~, OS X~~ and Windows
* Securely share your mounts over TCP/IP via `XChaCha20-Poly1305` with other systems on your network or over the internet. * Securely share your mounts over TCP/IP (`XChaCha20-Poly1305` stream cipher) with other systems on your network or the internet.
* Cross-platform support (Linux 64-bit, Linux arm64/aarch64, Windows 64-bit) * Cross-platform support (Linux 64-bit, Linux arm64/aarch64, ~~OS X,~~ Windows 64-bit)
* Optionally encrypt file names and file data via `XChaCha20-Poly1305` in S3 mounts
## Minimum Requirements ## Minimum Requirements
* [Sia renterd](https://github.com/SiaFoundation/renterd/releases) v2.0.0+ for Sia support * [Sia renterd](https://github.com/SiaFoundation/renterd/releases) v0.4.0+ for Sia support
* Only 64-bit operating systems are supported * Only 64-bit operating systems are supported
* By default, Linux requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support * By default, Linux requires `fusermount3`; otherwise, `repertory` must be manually compiled with `libfuse2` support
* ~~OS X requires the following dependency to be installed:~~
* ~~[FUSE for macOS v4.5.0](https://github.com/osxfuse/osxfuse/releases/download/macfuse-4.5.0/macfuse-4.5.0.dmg)~~
* Windows requires the following dependencies to be installed: * Windows requires the following dependencies to be installed:
* [WinFSP 2023](https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi) * [WinFSP 2023](https://github.com/winfsp/winfsp/releases/download/v2.0/winfsp-2.0.23075.msi)
@ -24,10 +25,40 @@ on Windows.
* Linux `arm64/aarch64` * Linux `arm64/aarch64`
* Linux `amd64` * Linux `amd64`
* ~~OS X Mojave and above~~
* Windows 64-bit 10, 11 * Windows 64-bit 10, 11
## Usage ## Usage
### Notable Options
* `-dc`
* Display mount configuration.
* For Sia, `--name` is optional
* For S3, the `-s3` option is required along with `--name`
* `--help`
* Display all mount utility options.
* `--name, -na [name]`
* The `--name` option can be set to any valid value allowed as a file name for your filesystem.
* For Sia, the bucket name will be set to the same value if it is empty in the configuration file.
* If the `--name` option is not specified, `default` will be used.
* For S3, the `--name` option is required and does not affect the bucket name.
* `-set SiaConfig.Bucket`
* Sets the Sia bucket name to mount.
* Can be used in combination with `--name` to target a unique configuration.
* `-set S3Config.Bucket`
* Sets the S3 bucket name to mount.
* Must be used in combination with `--name` to target a unique configuration.
* Must be used in combination with `-s3`.
### Data Directories
* Linux
* `~/.local/repertory2`
* Windows
* `%LOCALAPPDATA%\repertory2`
* i.e. `C:\\Users\\Tom\\AppData\\Local\\repertory2`
### Sia ### Sia
* Initial Configuration * Initial Configuration
@ -41,86 +72,45 @@ on Windows.
* For all other configurations: * For all other configurations:
* `repertory --name '<my config name>' -set HostConfig.ApiPassword '<my password>'` * `repertory --name '<my config name>' -set HostConfig.ApiPassword '<my password>'`
* `repertory --name '<my config name>' -set SiaConfig.Bucket '<my bucket name>'` * `repertory --name '<my config name>' -set SiaConfig.Bucket '<my bucket name>'`
* To verify/view all configuration options: * To verify all configuration options:
* `repertory -dc` * `repertory -dc` or `repertory --name '<my config name>' -dc`
* `repertory --name '<my config name>' -dc`
* Example:
* `repertory --name default -dc`
* Mounting on Linux: * Mounting on Linux:
* `repertory /mnt/location` * `repertory /mnt/location`
* `repertory --name '<my config name>' /mnt/location` * `repertory --name default /mnt/location`
* Example:
* `repertory --name default /mnt/location`
* Mounting on Windows: * Mounting on Windows:
* `repertory t:` * `repertory t:`
* `repertory --name '<my config name>' t:` * `repertory --name default t:`
* Example:
* `repertory --name default t:`
### S3 ### S3
* Initial Configuration * Initial Configuration
* S3 steps: * S3 steps:
* Set the appropriate base URL:
* `repertory -s3 --name '<my config name>' -set S3Config.URL '<my url>'`
* Example:
* `repertory -s3 --name minio -set S3Config.URL 'http://localhost:9000'`
* Set the appropriate bucket name: * Set the appropriate bucket name:
* `repertory -s3 --name '<my config name>' -set S3Config.Bucket '<my bucket name>'` * `repertory --name '<my config name>' -set S3Config.Bucket '<my bucket name>'`
* Set the appropriate base URL:
* `repertory --name '<my config name>' -set S3Config.URL '<my url>'`
* i.e. `repertory --name minio -set S3Config.URL 'http://localhost:9000'`
* Set the appropriate access key: * Set the appropriate access key:
* `repertory -s3 --name '<my config name>' -set S3Config.AccessKey '<my access key>'` * `repertory --name '<my config name>' -set S3Config.AccessKey '<my access key>'`
* Set the appropriate secret key: * Set the appropriate secret key:
* `repertory -s3 --name '<my config name>' -set S3Config.SecretKey '<my secret key>'` * `repertory --name '<my config name>' -set S3Config.SecretKey '<my secret key>'`
* For Sia and most local S3 gateway instances, enable path style URL's: * For Sia and most local S3 gateway instances, enable path style URL's:
* `repertory -s3 --name '<my config name>' -set S3Config.UsePathStyle true` * `repertory --name '<my config name>' -set S3Config.UsePathStyle true`
* Optional steps: * Optionally, set the appropriate region. Default is set to `any`:
* Set an appropriate region. Default is set to `any`: * `repertory --name '<my config name>' -set S3Config.Region '<my region>'`
* `repertory -s3 --name '<my config name>' -set S3Config.Region '<my region>'` * Optionally, to enable encrypted file names and file data, set a strong, random encryption token:
* Enable encrypted file names and file data. Set a strong, random encryption token and be sure to store it in a secure backup location: * `repertory --name '<my config name>' -set S3Config.EncryptionToken '<my strong password>'`
* `repertory -s3 --name '<my config name>' -set S3Config.EncryptionToken '<my strong password>'` * To verify all configuration options:
* To verify/view all configuration options: * `repertory -dc` or `repertory --name '<my config nam>' -dc`
* `repertory -s3 --name '<my config name>' -dc`
* Example:
* `repertory -s3 --name minio -dc`
* Mounting on Linux: * Mounting on Linux:
* `repertory -s3 --name '<my config name>' /mnt/location` * `repertory -s3 --name '<my config name>' /mnt/location`
* Example:
* `repertory -s3 --name minio /mnt/location`
* Mounting on Windows: * Mounting on Windows:
* `repertory -s3 --name '<my config name>' t:` * `repertory -s3 --name '<my config name>' t:`
* Example:
* `repertory -s3 --name minio t:`
### Notable Options
* `--help`
* Display all mount utility options
* `--name, -na [name]`
* The `--name` option can be set to any valid value allowed as a file name for your filesystem.
* For Sia, the bucket name will be set to the same value if it is empty in the configuration file.
* If the `--name` option is not specified, `default` will be used.
* For S3, the `--name` option is required and does not affect the bucket name.
* `-dc`
* Display mount configuration
* For Sia, `--name` is optional
* For S3, the `-s3` option is required along with `--name`
### Data Directories
* Linux
* `~/.local/repertory2`
* Windows
* `%LOCALAPPDATA%\repertory2`
* Example:
* `C:\Users\Tom\AppData\Local\repertory2`
* IMPORTANT:
* It is highly recommended to exclude this folder from any anti-virus/anti-malware applications as severe performance issues may arise.
* Excluding the mounted drive letter is also highly recommended.
## Remote Mounting ## Remote Mounting
`Repertory` allows local mounts to be shared with other computers on your network. `Repertory` allows local mounts to be shared with other computers on your network. This option is referred to as remote mounting.
This option is referred to as remote mounting. Instructions TBD. Instructions TBD.
## Compiling ## Compiling
@ -149,26 +139,17 @@ This option is referred to as remote mounting. Instructions TBD.
## Credits ## Credits
* [binutils](https://www.gnu.org/software/binutils/)
* [boost c++ libraries](https://www.boost.org/) * [boost c++ libraries](https://www.boost.org/)
* [cpp-httplib](https://github.com/yhirose/cpp-httplib) * [cpp-httplib](https://github.com/yhirose/cpp-httplib)
* [curl](https://curl.haxx.se/) * [curl](https://curl.haxx.se/)
* [docker](https://www.docker.com/) * ~~[FUSE for macOS](https://osxfuse.github.io/)~~
* [Google Test](https://github.com/google/googletest) * [Google Test](https://github.com/google/googletest)
* [ICU](https://icu.unicode.org/)
* [JSON for Modern C++](https://github.com/nlohmann/json) * [JSON for Modern C++](https://github.com/nlohmann/json)
* [libexpat](https://github.com/libexpat/libexpat)
* [libfuse](https://github.com/libfuse/libfuse) * [libfuse](https://github.com/libfuse/libfuse)
* [libsodium](https://doc.libsodium.org/) * [libsodium](https://doc.libsodium.org/)
* [mingw-w64](https://www.mingw-w64.org/)
* [MSYS2](https://www.msys2.org)
* [OpenSSL](https://www.openssl.org/) * [OpenSSL](https://www.openssl.org/)
* [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/)
* [pugixml](https://pugixml.org/)
* [RocksDB](https://rocksdb.org)
* [ScPrime](https://scpri.me/) * [ScPrime](https://scpri.me/)
* [Sia Decentralized Cloud Storage](https://sia.tech/) * [Sia Decentralized Cloud Storage](https://sia.tech/)
* [spdlog](https://github.com/gabime/spdlog)
* [SQLite](https://www.sqlite.org) * [SQLite](https://www.sqlite.org)
* [stduuid](https://github.com/mariusbancila/stduuid) * [stduuid](https://github.com/mariusbancila/stduuid)
* [Storj](https://storj.io/) * [Storj](https://storj.io/)

View File

@ -1,15 +1,15 @@
set(BINUTILS_VERSION 2.43) set(BINUTILS_VERSION 2.43)
set(BOOST2_MAJOR_VERSION 1)
set(BOOST2_MINOR_VERSION 76)
set(BOOST2_PATCH_VERSION 0)
set(BOOST_MAJOR_VERSION 1) set(BOOST_MAJOR_VERSION 1)
set(BOOST_MINOR_VERSION 87) set(BOOST_MINOR_VERSION 87)
set(BOOST_PATCH_VERSION 0) set(BOOST_PATCH_VERSION 0)
set(BOOST2_MAJOR_VERSION 1)
set(BOOST2_MINOR_VERSION 76)
set(BOOST2_PATCH_VERSION 0)
set(CPP_HTTPLIB_VERSION 0.18.1) set(CPP_HTTPLIB_VERSION 0.18.1)
set(CURL2_VERSION 8_11_0)
set(CURL_VERSION 8.11.0) set(CURL_VERSION 8.11.0)
set(EXPAT2_VERSION 2_6_4) set(CURL2_VERSION 8_11_0)
set(EXPAT_VERSION 2.6.4) set(EXPAT_VERSION 2.6.4)
set(EXPAT2_VERSION 2_6_4)
set(GCC_VERSION 14.2.0) set(GCC_VERSION 14.2.0)
set(GTEST_VERSION 1.15.2) set(GTEST_VERSION 1.15.2)
set(ICU_VERSION 76-1) set(ICU_VERSION 76-1)
@ -22,7 +22,7 @@ set(PKG_CONFIG_VERSION 0.29.2)
set(PUGIXML_VERSION 1.14) set(PUGIXML_VERSION 1.14)
set(ROCKSDB_VERSION 9.7.4) set(ROCKSDB_VERSION 9.7.4)
set(SPDLOG_VERSION 1.15.0) set(SPDLOG_VERSION 1.15.0)
set(SQLITE2_VERSION 3.46.1)
set(SQLITE_VERSION 3460100) set(SQLITE_VERSION 3460100)
set(SQLITE2_VERSION 3.46.1)
set(STDUUID_VERSION 1.2.3) set(STDUUID_VERSION 1.2.3)
set(ZLIB_VERSION 1.3.1) set(ZLIB_VERSION 1.3.1)

View File

@ -10,7 +10,7 @@ PROJECT_DESC="Mount utility for Sia and S3"
PROJECT_MAJOR_VERSION=2 PROJECT_MAJOR_VERSION=2
PROJECT_MINOR_VERSION=0 PROJECT_MINOR_VERSION=0
PROJECT_REVISION_VERSION=4 PROJECT_REVISION_VERSION=3
PROJECT_RELEASE_NUM=0 PROJECT_RELEASE_NUM=0
PROJECT_RELEASE_ITER=rc PROJECT_RELEASE_ITER=rc

View File

@ -1,5 +1,4 @@
#comment FROM arm64v8/alpine:3.21.0
FROM arm64v8/alpine:3.21.3
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com> MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
CMD bash CMD bash

View File

@ -1,5 +1,4 @@
#comment FROM alpine:3.21.0
FROM alpine:3.21.3
MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com> MAINTAINER Scott E. Graves <scott.e.graves@protonmail.com>
CMD bash CMD bash

View File

@ -1,5 +1,5 @@
#comment #comment
FROM alpine:3.21.3 FROM alpine:3.21.0
RUN apk update RUN apk update
RUN apk upgrade RUN apk upgrade

View File

@ -31,26 +31,26 @@ private:
static stop_type stop_requested; static stop_type stop_requested;
public: public:
[[nodiscard]] static auto default_agent_name(const provider_type &prov) [[nodiscard]] static auto
-> std::string; default_agent_name(const provider_type &prov) -> std::string;
[[nodiscard]] static auto default_api_port(const provider_type &prov) [[nodiscard]] static auto
-> std::uint16_t; default_api_port(const provider_type &prov) -> std::uint16_t;
[[nodiscard]] static auto default_data_directory(const provider_type &prov) [[nodiscard]] static auto
-> std::string; default_data_directory(const provider_type &prov) -> std::string;
[[nodiscard]] static auto default_remote_api_port(const provider_type &prov) [[nodiscard]] static auto
-> std::uint16_t; default_remote_api_port(const provider_type &prov) -> std::uint16_t;
[[nodiscard]] static auto default_rpc_port(const provider_type &prov) [[nodiscard]] static auto
-> std::uint16_t; default_rpc_port(const provider_type &prov) -> std::uint16_t;
[[nodiscard]] static auto get_provider_display_name(const provider_type &prov) [[nodiscard]] static auto
-> std::string; get_provider_display_name(const provider_type &prov) -> std::string;
[[nodiscard]] static auto get_provider_name(const provider_type &prov) [[nodiscard]] static auto
-> std::string; get_provider_name(const provider_type &prov) -> std::string;
public: public:
[[nodiscard]] static auto get_stop_requested() -> bool; [[nodiscard]] static auto get_stop_requested() -> bool;
@ -91,6 +91,7 @@ private:
std::atomic<std::uint8_t> max_upload_count_; std::atomic<std::uint8_t> max_upload_count_;
std::atomic<std::uint16_t> med_freq_interval_secs_; std::atomic<std::uint16_t> med_freq_interval_secs_;
std::atomic<std::uint16_t> online_check_retry_secs_; std::atomic<std::uint16_t> online_check_retry_secs_;
std::atomic<std::uint16_t> orphaned_file_retention_days_;
std::atomic<download_type> preferred_download_type_; std::atomic<download_type> preferred_download_type_;
std::atomic<std::uint16_t> retry_read_count_; std::atomic<std::uint16_t> retry_read_count_;
std::atomic<std::uint16_t> ring_buffer_file_size_; std::atomic<std::uint16_t> ring_buffer_file_size_;
@ -171,6 +172,8 @@ public:
[[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t; [[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t;
[[nodiscard]] auto get_orphaned_file_retention_days() const -> std::uint16_t;
[[nodiscard]] auto get_preferred_download_type() const -> download_type; [[nodiscard]] auto get_preferred_download_type() const -> download_type;
[[nodiscard]] auto get_provider_type() const -> provider_type; [[nodiscard]] auto get_provider_type() const -> provider_type;
@ -189,11 +192,8 @@ public:
[[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t; [[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t;
[[nodiscard]] auto get_value_by_name(const std::string &name) const [[nodiscard]] auto
-> std::string; get_value_by_name(const std::string &name) const -> std::string;
[[nodiscard]] auto get_raw_value_by_name(const std::string &name) const
-> std::string;
[[nodiscard]] auto get_version() const -> std::uint64_t; [[nodiscard]] auto get_version() const -> std::uint64_t;
@ -239,6 +239,8 @@ public:
void set_online_check_retry_secs(std::uint16_t value); void set_online_check_retry_secs(std::uint16_t value);
void set_orphaned_file_retention_days(std::uint16_t value);
void set_preferred_download_type(const download_type &value); void set_preferred_download_type(const download_type &value);
void set_remote_config(remote::remote_config value); void set_remote_config(remote::remote_config value);

View File

@ -57,7 +57,7 @@ using json = nlohmann::json;
inline constexpr const std::string_view REPERTORY = "repertory"; inline constexpr const std::string_view REPERTORY = "repertory";
inline constexpr const std::wstring_view REPERTORY_W = L"repertory"; inline constexpr const std::wstring_view REPERTORY_W = L"repertory";
inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 1ULL; inline constexpr const std::uint64_t REPERTORY_CONFIG_VERSION = 0ULL;
inline constexpr const std::string_view REPERTORY_DATA_NAME = "repertory2"; inline constexpr const std::string_view REPERTORY_DATA_NAME = "repertory2";
inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0"; inline constexpr const std::string_view REPERTORY_MIN_REMOTE_VERSION = "2.0.0";
@ -221,25 +221,44 @@ using WCHAR = wchar_t;
#define MAX_PATH 260 #define MAX_PATH 260
#define STATUS_SUCCESS std::uint32_t{0U} #define STATUS_SUCCESS \
#define STATUS_ACCESS_DENIED std::uint32_t{0xC0000022L} std::uint32_t { 0U }
#define STATUS_DEVICE_BUSY std::uint32_t{0x80000011L} #define STATUS_ACCESS_DENIED \
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES std::uint32_t{0xC0000468L} std::uint32_t { 0xC0000022L }
#define STATUS_DIRECTORY_NOT_EMPTY std::uint32_t{0xC0000101L} #define STATUS_DEVICE_BUSY \
#define STATUS_FILE_IS_A_DIRECTORY std::uint32_t{0xC00000BAL} std::uint32_t { 0x80000011L }
#define STATUS_FILE_TOO_LARGE std::uint32_t{0xC0000904L} #define STATUS_DEVICE_INSUFFICIENT_RESOURCES \
#define STATUS_INSUFFICIENT_RESOURCES std::uint32_t{0xC000009AL} std::uint32_t { 0xC0000468L }
#define STATUS_INTERNAL_ERROR std::uint32_t{0xC00000E5L} #define STATUS_DIRECTORY_NOT_EMPTY \
#define STATUS_INVALID_ADDRESS std::uint32_t{0xC0000141L} std::uint32_t { 0xC0000101L }
#define STATUS_INVALID_HANDLE std::uint32_t{0xC0000006L} #define STATUS_FILE_IS_A_DIRECTORY \
#define STATUS_INVALID_IMAGE_FORMAT std::uint32_t{0xC000007BL} std::uint32_t { 0xC00000BAL }
#define STATUS_INVALID_PARAMETER std::uint32_t{0xC000000DL} #define STATUS_FILE_TOO_LARGE \
#define STATUS_NO_MEMORY std::uint32_t{0xC0000017L} std::uint32_t { 0xC0000904L }
#define STATUS_NOT_IMPLEMENTED std::uint32_t{0xC0000002L} #define STATUS_INSUFFICIENT_RESOURCES \
#define STATUS_OBJECT_NAME_EXISTS std::uint32_t{0x40000000L} std::uint32_t { 0xC000009AL }
#define STATUS_OBJECT_NAME_NOT_FOUND std::uint32_t{0xC0000034L} #define STATUS_INTERNAL_ERROR \
#define STATUS_OBJECT_PATH_INVALID std::uint32_t{0xC0000039L} std::uint32_t { 0xC00000E5L }
#define STATUS_UNEXPECTED_IO_ERROR std::uint32_t{0xC00000E9L} #define STATUS_INVALID_ADDRESS \
std::uint32_t { 0xC0000141L }
#define STATUS_INVALID_HANDLE \
std::uint32_t { 0xC0000006L }
#define STATUS_INVALID_IMAGE_FORMAT \
std::uint32_t { 0xC000007BL }
#define STATUS_INVALID_PARAMETER \
std::uint32_t { 0xC000000DL }
#define STATUS_NO_MEMORY \
std::uint32_t { 0xC0000017L }
#define STATUS_NOT_IMPLEMENTED \
std::uint32_t { 0xC0000002L }
#define STATUS_OBJECT_NAME_EXISTS \
std::uint32_t { 0x40000000L }
#define STATUS_OBJECT_NAME_NOT_FOUND \
std::uint32_t { 0xC0000034L }
#define STATUS_OBJECT_PATH_INVALID \
std::uint32_t { 0xC0000039L }
#define STATUS_UNEXPECTED_IO_ERROR \
std::uint32_t { 0xC00000E9L }
#define CONVERT_STATUS_NOT_IMPLEMENTED(e) \ #define CONVERT_STATUS_NOT_IMPLEMENTED(e) \
((std::uint32_t(e) == STATUS_NOT_IMPLEMENTED) ? -ENOTSUP : e) ((std::uint32_t(e) == STATUS_NOT_IMPLEMENTED) ? -ENOTSUP : e)

View File

@ -26,7 +26,6 @@
#include "comm/packet/packet_client.hpp" #include "comm/packet/packet_client.hpp"
#include "drives/remote/remote_open_file_table.hpp" #include "drives/remote/remote_open_file_table.hpp"
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp" #include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
#include "types/remote.hpp"
namespace repertory { namespace repertory {
class app_config; class app_config;

View File

@ -1,78 +0,0 @@
/*
Copyright <2018-2025> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_EVENTS_TYPES_PRODIVER_INVALID_VERSION_HPP_
#define REPERTORY_INCLUDE_EVENTS_TYPES_PRODIVER_INVALID_VERSION_HPP_
#include "events/i_event.hpp"
#include "types/repertory.hpp"
namespace repertory {
struct provider_invalid_version final : public i_event {
provider_invalid_version() = default;
provider_invalid_version(std::string_view function_name_,
std::string required_version_,
std::string returned_version_)
: function_name(std::string(function_name_)),
required_version(std::move(required_version_)),
returned_version(std::move(returned_version_)) {}
static constexpr const event_level level{event_level::error};
static constexpr const std::string_view name{"provider_invalid_version"};
std::string function_name;
std::string required_version;
std::string returned_version;
[[nodiscard]] auto get_event_level() const -> event_level override {
return level;
}
[[nodiscard]] auto get_name() const -> std::string_view override {
return name;
}
[[nodiscard]] auto get_single_line() const -> std::string override {
return fmt::format("{}|func|{}|required|{}|returned|{}", name,
function_name, required_version, returned_version);
}
};
} // namespace repertory
NLOHMANN_JSON_NAMESPACE_BEGIN
template <> struct adl_serializer<repertory::provider_invalid_version> {
static void to_json(json &data,
const repertory::provider_invalid_version &value) {
data["function_name"] = value.function_name;
data["required_version"] = value.required_version;
data["returned_version"] = value.returned_version;
}
static void from_json(const json &data,
repertory::provider_invalid_version &value) {
data.at("function_name").get_to(value.function_name);
data.at("required_version").get_to(value.required_version);
data.at("returned_version").get_to(value.returned_version);
}
};
NLOHMANN_JSON_NAMESPACE_END
#endif // REPERTORY_INCLUDE_EVENTS_TYPES_PRODIVER_INVALID_VERSION_HPP_

View File

@ -85,13 +85,6 @@ private:
void remove_deleted_files(stop_type &stop_requested); void remove_deleted_files(stop_type &stop_requested);
public: public:
[[nodiscard]] auto check_version(std::string &required_version,
std::string &returned_version) const
-> bool override {
required_version = returned_version = "";
return true;
}
[[nodiscard]] auto create_directory(const std::string &api_path, [[nodiscard]] auto create_directory(const std::string &api_path,
api_meta_map &meta) -> api_error override; api_meta_map &meta) -> api_error override;

View File

@ -31,10 +31,6 @@ class i_provider {
INTERFACE_SETUP(i_provider); INTERFACE_SETUP(i_provider);
public: public:
[[nodiscard]] virtual auto check_version(std::string &required_version,
std::string &returned_version) const
-> bool = 0;
[[nodiscard]] virtual auto create_directory(const std::string &api_path, [[nodiscard]] virtual auto create_directory(const std::string &api_path,
api_meta_map &meta) api_meta_map &meta)
-> api_error = 0; -> api_error = 0;

View File

@ -113,13 +113,6 @@ protected:
-> api_error override; -> api_error override;
public: public:
[[nodiscard]] auto check_version(std::string &required_version,
std::string &returned_version) const
-> bool override {
required_version = returned_version = "";
return true;
}
[[nodiscard]] static auto convert_api_date(std::string_view date) [[nodiscard]] static auto convert_api_date(std::string_view date)
-> std::uint64_t; -> std::uint64_t;

View File

@ -80,10 +80,6 @@ protected:
-> api_error override; -> api_error override;
public: public:
[[nodiscard]] auto check_version(std::string &required_version,
std::string &returned_version) const
-> bool override;
[[nodiscard]] auto get_directory_item_count(const std::string &api_path) const [[nodiscard]] auto get_directory_item_count(const std::string &api_path) const
-> std::uint64_t override; -> std::uint64_t override;

View File

@ -24,27 +24,29 @@
namespace repertory { namespace repertory {
constexpr const auto default_api_auth_size{48U}; constexpr const auto default_api_auth_size{48U};
constexpr const auto default_download_timeout_secs{30U}; constexpr const auto default_download_timeout_ces{30U};
constexpr const auto default_eviction_delay_mins{1U}; constexpr const auto default_eviction_delay_mins{1U};
constexpr const auto default_high_freq_interval_secs{std::uint16_t{30U}}; constexpr const auto default_high_freq_interval_secs{30U};
constexpr const auto default_low_freq_interval_secs{std::uint16_t(60U * 60U)}; constexpr const auto default_low_freq_interval_secs{0U * 60U};
constexpr const auto default_max_cache_size_bytes{ constexpr const auto default_max_cache_size_bytes{
std::uint64_t(20ULL * 1024ULL * 1024ULL * 1024ULL), std::uint64_t(20UL * 1024UL * 1024UL * 1024UL),
}; };
constexpr const auto default_max_upload_count{5U}; constexpr const auto default_max_upload_count{5U};
constexpr const auto default_med_freq_interval_secs{std::uint16_t{2U * 60U}}; constexpr const auto default_med_freq_interval_secs{2U * 60U};
constexpr const auto default_online_check_retry_secs{60U}; constexpr const auto default_online_check_retry_secs{60U};
constexpr const auto default_orphaned_file_retention_days{15U};
constexpr const auto default_retry_read_count{6U}; constexpr const auto default_retry_read_count{6U};
constexpr const auto default_ring_buffer_file_size{512U}; constexpr const auto default_ring_buffer_file_size{512U};
constexpr const auto default_task_wait_ms{100U}; constexpr const auto default_task_wait_ms{100U};
constexpr const auto default_timeout_ms{60000U}; constexpr const auto default_timeout_ms{60000U};
constexpr const auto max_orphaned_file_retention_days{std::uint16_t(31U)};
constexpr const auto max_ring_buffer_file_size{std::uint16_t(1024U)}; constexpr const auto max_ring_buffer_file_size{std::uint16_t(1024U)};
constexpr const auto max_s3_object_name_length{1024U}; constexpr const auto max_s3_object_name_length{1024U};
constexpr const auto min_cache_size_bytes{ constexpr const auto min_cache_size_bytes{
std::uint64_t(100ULL * 1024ULL * 1024ULL), std::uint64_t(100UL * 1024UL * 1024UL)};
};
constexpr const auto min_download_timeout_secs{std::uint8_t(5U)}; constexpr const auto min_download_timeout_secs{std::uint8_t(5U)};
constexpr const auto min_online_check_retry_secs{std::uint16_t(15U)}; constexpr const auto min_online_check_retry_secs{std::uint16_t(15U)};
constexpr const auto min_orphaned_file_retention_days{std::uint16_t(1U)};
constexpr const auto min_retry_read_count{std::uint16_t(2U)}; constexpr const auto min_retry_read_count{std::uint16_t(2U)};
constexpr const auto min_ring_buffer_file_size{std::uint16_t(64U)}; constexpr const auto min_ring_buffer_file_size{std::uint16_t(64U)};
constexpr const auto min_task_wait_ms{std::uint16_t(50U)}; constexpr const auto min_task_wait_ms{std::uint16_t(50U)};
@ -330,6 +332,7 @@ struct directory_item final {
bool directory{false}; bool directory{false};
std::uint64_t size{}; std::uint64_t size{};
api_meta_map meta; api_meta_map meta;
bool resolved{false};
}; };
struct encrypt_config final { struct encrypt_config final {
@ -489,6 +492,8 @@ inline constexpr const auto JSON_MED_FREQ_INTERVAL_SECS{
inline constexpr const auto JSON_META{"Meta"}; inline constexpr const auto JSON_META{"Meta"};
inline constexpr const auto JSON_ONLINE_CHECK_RETRY_SECS{ inline constexpr const auto JSON_ONLINE_CHECK_RETRY_SECS{
"OnlineCheckRetrySeconds"}; "OnlineCheckRetrySeconds"};
inline constexpr const auto JSON_ORPHANED_FILE_RETENTION_DAYS{
"OrphanedFileRetentionDays"};
inline constexpr const auto JSON_PATH{"Path"}; inline constexpr const auto JSON_PATH{"Path"};
inline constexpr const auto JSON_PREFERRED_DOWNLOAD_TYPE{ inline constexpr const auto JSON_PREFERRED_DOWNLOAD_TYPE{
"PreferredDownloadType"}; "PreferredDownloadType"};
@ -613,16 +618,6 @@ template <typename data_t> struct adl_serializer<repertory::atomic<data_t>> {
} }
}; };
template <> struct adl_serializer<std::atomic<std::uint64_t>> {
static void to_json(json &data, const std::atomic<std::uint64_t> &value) {
data = value.load();
}
static void from_json(const json &data, std::atomic<std::uint64_t> &value) {
value.store(data.get<std::uint64_t>());
}
};
template <typename primitive_t> template <typename primitive_t>
struct adl_serializer<std::atomic<primitive_t>> { struct adl_serializer<std::atomic<primitive_t>> {
static void to_json(json &data, const std::atomic<primitive_t> &value) { static void to_json(json &data, const std::atomic<primitive_t> &value) {
@ -646,18 +641,6 @@ template <> struct adl_serializer<std::atomic<repertory::database_type>> {
} }
}; };
template <> struct adl_serializer<std::atomic<repertory::event_level>> {
static void to_json(json &data,
const std::atomic<repertory::event_level> &value) {
data = repertory::event_level_to_string(value.load());
}
static void from_json(const json &data,
std::atomic<repertory::event_level> &value) {
value.store(repertory::event_level_from_string(data.get<std::string>()));
}
};
template <> struct adl_serializer<std::atomic<repertory::download_type>> { template <> struct adl_serializer<std::atomic<repertory::download_type>> {
static void to_json(json &data, static void to_json(json &data,
const std::atomic<repertory::download_type> &value) { const std::atomic<repertory::download_type> &value) {
@ -690,13 +673,15 @@ template <> struct adl_serializer<repertory::download_type> {
} }
}; };
template <> struct adl_serializer<repertory::event_level> { template <> struct adl_serializer<std::atomic<repertory::event_level>> {
static void to_json(json &data, const repertory::event_level &value) { static void to_json(json &data,
data = repertory::event_level_to_string(value); const std::atomic<repertory::event_level> &value) {
data = repertory::event_level_to_string(value.load());
} }
static void from_json(const json &data, repertory::event_level &value) { static void from_json(const json &data,
value = repertory::event_level_from_string(data.get<std::string>()); std::atomic<repertory::event_level> &value) {
value.store(repertory::event_level_from_string(data.get<std::string>()));
} }
}; };
NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_END

View File

@ -70,7 +70,7 @@ app_config::app_config(const provider_type &prov,
api_port_(default_rpc_port(prov)), api_port_(default_rpc_port(prov)),
api_user_(std::string{REPERTORY}), api_user_(std::string{REPERTORY}),
config_changed_(false), config_changed_(false),
download_timeout_secs_(default_download_timeout_secs), download_timeout_secs_(default_download_timeout_ces),
enable_download_timeout_(true), enable_download_timeout_(true),
enable_drive_events_(false), enable_drive_events_(false),
#if defined(_WIN32) #if defined(_WIN32)
@ -85,6 +85,7 @@ app_config::app_config(const provider_type &prov,
max_upload_count_(default_max_upload_count), max_upload_count_(default_max_upload_count),
med_freq_interval_secs_(default_med_freq_interval_secs), med_freq_interval_secs_(default_med_freq_interval_secs),
online_check_retry_secs_(default_online_check_retry_secs), online_check_retry_secs_(default_online_check_retry_secs),
orphaned_file_retention_days_(default_orphaned_file_retention_days),
preferred_download_type_(download_type::default_), preferred_download_type_(download_type::default_),
retry_read_count_(default_retry_read_count), retry_read_count_(default_retry_read_count),
ring_buffer_file_size_(default_ring_buffer_file_size), ring_buffer_file_size_(default_ring_buffer_file_size),
@ -165,14 +166,8 @@ app_config::app_config(const provider_type &prov,
[this]() { return get_host_config().api_password; }}, [this]() { return get_host_config().api_password; }},
{fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_API_PORT), {fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_API_PORT),
[this]() { return std::to_string(get_host_config().api_port); }}, [this]() { return std::to_string(get_host_config().api_port); }},
{fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_API_USER),
[this]() { return get_host_config().api_user; }},
{fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_HOST_NAME_OR_IP), {fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_HOST_NAME_OR_IP),
[this]() { return get_host_config().host_name_or_ip; }}, [this]() { return get_host_config().host_name_or_ip; }},
{fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_PATH),
[this]() { return get_host_config().path; }},
{fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_PROTOCOL),
[this]() { return get_host_config().protocol; }},
{fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_TIMEOUT_MS), {fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_TIMEOUT_MS),
[this]() { return std::to_string(get_host_config().timeout_ms); }}, [this]() { return std::to_string(get_host_config().timeout_ms); }},
{JSON_LOW_FREQ_INTERVAL_SECS, {JSON_LOW_FREQ_INTERVAL_SECS,
@ -185,6 +180,8 @@ app_config::app_config(const provider_type &prov,
[this]() { return std::to_string(get_med_frequency_interval_secs()); }}, [this]() { return std::to_string(get_med_frequency_interval_secs()); }},
{JSON_ONLINE_CHECK_RETRY_SECS, {JSON_ONLINE_CHECK_RETRY_SECS,
[this]() { return std::to_string(get_online_check_retry_secs()); }}, [this]() { return std::to_string(get_online_check_retry_secs()); }},
{JSON_ORPHANED_FILE_RETENTION_DAYS,
[this]() { return std::to_string(get_orphaned_file_retention_days()); }},
{JSON_PREFERRED_DOWNLOAD_TYPE, {JSON_PREFERRED_DOWNLOAD_TYPE,
[this]() { [this]() {
return download_type_to_string(get_preferred_download_type()); return download_type_to_string(get_preferred_download_type());
@ -253,7 +250,7 @@ app_config::app_config(const provider_type &prov,
value_set_lookup_ = { value_set_lookup_ = {
{ {
JSON_API_AUTH, JSON_API_PATH,
[this](const std::string &value) { [this](const std::string &value) {
set_api_auth(value); set_api_auth(value);
return get_api_auth(); return get_api_auth();
@ -352,7 +349,7 @@ app_config::app_config(const provider_type &prov,
{ {
JSON_HIGH_FREQ_INTERVAL_SECS, JSON_HIGH_FREQ_INTERVAL_SECS,
[this](const std::string &value) { [this](const std::string &value) {
set_high_frequency_interval_secs(utils::string::to_uint16(value)); set_high_frequency_interval_secs(utils::string::to_uint8(value));
return std::to_string(get_high_frequency_interval_secs()); return std::to_string(get_high_frequency_interval_secs());
}, },
}, },
@ -383,15 +380,6 @@ app_config::app_config(const provider_type &prov,
return std::to_string(get_host_config().api_port); return std::to_string(get_host_config().api_port);
}, },
}, },
{
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_API_USER),
[this](const std::string &value) {
auto cfg = get_host_config();
cfg.api_user = value;
set_host_config(cfg);
return get_host_config().api_user;
},
},
{ {
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_HOST_NAME_OR_IP), fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_HOST_NAME_OR_IP),
[this](const std::string &value) { [this](const std::string &value) {
@ -401,24 +389,6 @@ app_config::app_config(const provider_type &prov,
return get_host_config().host_name_or_ip; return get_host_config().host_name_or_ip;
}, },
}, },
{
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_PATH),
[this](const std::string &value) {
auto cfg = get_host_config();
cfg.path = value;
set_host_config(cfg);
return get_host_config().path;
},
},
{
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_PROTOCOL),
[this](const std::string &value) {
auto cfg = get_host_config();
cfg.protocol = value;
set_host_config(cfg);
return get_host_config().protocol;
},
},
{ {
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_TIMEOUT_MS), fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_TIMEOUT_MS),
[this](const std::string &value) { [this](const std::string &value) {
@ -431,14 +401,14 @@ app_config::app_config(const provider_type &prov,
{ {
JSON_LOW_FREQ_INTERVAL_SECS, JSON_LOW_FREQ_INTERVAL_SECS,
[this](const std::string &value) { [this](const std::string &value) {
set_low_frequency_interval_secs(utils::string::to_uint16(value)); set_low_frequency_interval_secs(utils::string::to_uint8(value));
return std::to_string(get_low_frequency_interval_secs()); return std::to_string(get_low_frequency_interval_secs());
}, },
}, },
{ {
JSON_MED_FREQ_INTERVAL_SECS, JSON_MED_FREQ_INTERVAL_SECS,
[this](const std::string &value) { [this](const std::string &value) {
set_med_frequency_interval_secs(utils::string::to_uint16(value)); set_med_frequency_interval_secs(utils::string::to_uint8(value));
return std::to_string(get_med_frequency_interval_secs()); return std::to_string(get_med_frequency_interval_secs());
}, },
}, },
@ -463,6 +433,13 @@ app_config::app_config(const provider_type &prov,
return std::to_string(get_online_check_retry_secs()); return std::to_string(get_online_check_retry_secs());
}, },
}, },
{
JSON_ORPHANED_FILE_RETENTION_DAYS,
[this](const std::string &value) {
set_orphaned_file_retention_days(utils::string::to_uint16(value));
return std::to_string(get_orphaned_file_retention_days());
},
},
{ {
JSON_PREFERRED_DOWNLOAD_TYPE, JSON_PREFERRED_DOWNLOAD_TYPE,
[this](const std::string &value) { [this](const std::string &value) {
@ -835,6 +812,7 @@ auto app_config::get_json() const -> json {
{JSON_MAX_UPLOAD_COUNT, max_upload_count_}, {JSON_MAX_UPLOAD_COUNT, max_upload_count_},
{JSON_MED_FREQ_INTERVAL_SECS, med_freq_interval_secs_}, {JSON_MED_FREQ_INTERVAL_SECS, med_freq_interval_secs_},
{JSON_ONLINE_CHECK_RETRY_SECS, online_check_retry_secs_}, {JSON_ONLINE_CHECK_RETRY_SECS, online_check_retry_secs_},
{JSON_ORPHANED_FILE_RETENTION_DAYS, orphaned_file_retention_days_},
{JSON_PREFERRED_DOWNLOAD_TYPE, preferred_download_type_}, {JSON_PREFERRED_DOWNLOAD_TYPE, preferred_download_type_},
{JSON_REMOTE_CONFIG, remote_config_}, {JSON_REMOTE_CONFIG, remote_config_},
{JSON_REMOTE_MOUNT, remote_mount_}, {JSON_REMOTE_MOUNT, remote_mount_},
@ -856,6 +834,7 @@ auto app_config::get_json() const -> json {
ret.erase(JSON_MAX_CACHE_SIZE_BYTES); ret.erase(JSON_MAX_CACHE_SIZE_BYTES);
ret.erase(JSON_MAX_UPLOAD_COUNT); ret.erase(JSON_MAX_UPLOAD_COUNT);
ret.erase(JSON_ONLINE_CHECK_RETRY_SECS); ret.erase(JSON_ONLINE_CHECK_RETRY_SECS);
ret.erase(JSON_ORPHANED_FILE_RETENTION_DAYS);
ret.erase(JSON_PREFERRED_DOWNLOAD_TYPE); ret.erase(JSON_PREFERRED_DOWNLOAD_TYPE);
ret.erase(JSON_REMOTE_CONFIG); ret.erase(JSON_REMOTE_CONFIG);
ret.erase(JSON_RETRY_READ_COUNT); ret.erase(JSON_RETRY_READ_COUNT);
@ -877,6 +856,7 @@ auto app_config::get_json() const -> json {
ret.erase(JSON_MAX_UPLOAD_COUNT); ret.erase(JSON_MAX_UPLOAD_COUNT);
ret.erase(JSON_MED_FREQ_INTERVAL_SECS); ret.erase(JSON_MED_FREQ_INTERVAL_SECS);
ret.erase(JSON_ONLINE_CHECK_RETRY_SECS); ret.erase(JSON_ONLINE_CHECK_RETRY_SECS);
ret.erase(JSON_ORPHANED_FILE_RETENTION_DAYS);
ret.erase(JSON_PREFERRED_DOWNLOAD_TYPE); ret.erase(JSON_PREFERRED_DOWNLOAD_TYPE);
ret.erase(JSON_REMOTE_MOUNT); ret.erase(JSON_REMOTE_MOUNT);
ret.erase(JSON_RETRY_READ_COUNT); ret.erase(JSON_RETRY_READ_COUNT);
@ -932,6 +912,12 @@ auto app_config::get_online_check_retry_secs() const -> std::uint16_t {
return std::max(min_online_check_retry_secs, online_check_retry_secs_.load()); return std::max(min_online_check_retry_secs, online_check_retry_secs_.load());
} }
auto app_config::get_orphaned_file_retention_days() const -> std::uint16_t {
return std::min(max_orphaned_file_retention_days,
std::max(min_orphaned_file_retention_days,
orphaned_file_retention_days_.load()));
}
auto app_config::get_preferred_download_type() const -> download_type { auto app_config::get_preferred_download_type() const -> download_type {
return preferred_download_type_; return preferred_download_type_;
} }
@ -1067,6 +1053,8 @@ auto app_config::load() -> bool {
med_freq_interval_secs_, found); med_freq_interval_secs_, found);
get_value(json_document, JSON_ONLINE_CHECK_RETRY_SECS, get_value(json_document, JSON_ONLINE_CHECK_RETRY_SECS,
online_check_retry_secs_, found); online_check_retry_secs_, found);
get_value(json_document, JSON_ORPHANED_FILE_RETENTION_DAYS,
orphaned_file_retention_days_, found);
get_value(json_document, JSON_PREFERRED_DOWNLOAD_TYPE, get_value(json_document, JSON_PREFERRED_DOWNLOAD_TYPE,
preferred_download_type_, found); preferred_download_type_, found);
get_value(json_document, JSON_REMOTE_CONFIG, remote_config_, found); get_value(json_document, JSON_REMOTE_CONFIG, remote_config_, found);
@ -1081,17 +1069,10 @@ auto app_config::load() -> bool {
std::uint64_t version{}; std::uint64_t version{};
get_value(json_document, JSON_VERSION, version, found); get_value(json_document, JSON_VERSION, version, found);
// Handle configuration defaults for new config versions
if (version != REPERTORY_CONFIG_VERSION) { if (version != REPERTORY_CONFIG_VERSION) {
version_ = REPERTORY_CONFIG_VERSION; version_ = REPERTORY_CONFIG_VERSION;
if (version_ == 1U) { // TODO upgrade future version
if (low_freq_interval_secs_ == 0UL) {
set_value(low_freq_interval_secs_, default_low_freq_interval_secs);
}
if (max_cache_size_bytes_ == 0UL) {
set_value(max_cache_size_bytes_, default_max_cache_size_bytes);
}
}
found = false; found = false;
} }
@ -1218,6 +1199,10 @@ void app_config::set_online_check_retry_secs(std::uint16_t value) {
set_value(online_check_retry_secs_, value); set_value(online_check_retry_secs_, value);
} }
void app_config::set_orphaned_file_retention_days(std::uint16_t value) {
set_value(orphaned_file_retention_days_, value);
}
void app_config::set_preferred_download_type(const download_type &value) { void app_config::set_preferred_download_type(const download_type &value) {
set_value(preferred_download_type_, value); set_value(preferred_download_type_, value);
} }

View File

@ -43,8 +43,8 @@
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory::remote_fuse { namespace repertory::remote_fuse {
auto remote_fuse_drive::access_impl(std::string api_path, int mask) auto remote_fuse_drive::access_impl(std::string api_path,
-> api_error { int mask) -> api_error {
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_access(api_path.c_str(), mask)); remote_instance_->fuse_access(api_path.c_str(), mask));
} }
@ -62,8 +62,8 @@ auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode,
struct fuse_file_info * /*f_info*/) struct fuse_file_info * /*f_info*/)
-> api_error { -> api_error {
#else #else
auto remote_fuse_drive::chmod_impl(std::string api_path, mode_t mode) auto remote_fuse_drive::chmod_impl(std::string api_path,
-> api_error { mode_t mode) -> api_error {
#endif #endif
return utils::to_api_error(remote_instance_->fuse_chmod( return utils::to_api_error(remote_instance_->fuse_chmod(
api_path.c_str(), static_cast<remote::file_mode>(mode))); api_path.c_str(), static_cast<remote::file_mode>(mode)));
@ -74,8 +74,8 @@ auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid,
struct fuse_file_info * /*f_info*/) struct fuse_file_info * /*f_info*/)
-> api_error { -> api_error {
#else #else
auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid) auto remote_fuse_drive::chown_impl(std::string api_path, uid_t uid,
-> api_error { gid_t gid) -> api_error {
#endif #endif
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_chown(api_path.c_str(), uid, gid)); remote_instance_->fuse_chown(api_path.c_str(), uid, gid));
@ -94,7 +94,7 @@ void remote_fuse_drive::destroy_impl(void *ptr) {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
event_system::instance().raise<drive_unmount_pending>(function_name, event_system::instance().raise<drive_unmount_pending>(function_name,
get_mount_location()); get_mount_location());
if (server_) { if (server_) {
server_->stop(); server_->stop();
@ -116,15 +116,14 @@ void remote_fuse_drive::destroy_impl(void *ptr) {
} }
event_system::instance().raise<drive_unmounted>(function_name, event_system::instance().raise<drive_unmounted>(function_name,
get_mount_location()); get_mount_location());
fuse_base::destroy_impl(ptr); fuse_base::destroy_impl(ptr);
} }
auto remote_fuse_drive::fgetattr_impl(std::string api_path, auto remote_fuse_drive::fgetattr_impl(
struct stat *unix_st, std::string api_path, struct stat *unix_st,
struct fuse_file_info *f_info) struct fuse_file_info *f_info) -> api_error {
-> api_error {
remote::stat r_stat{}; remote::stat r_stat{};
auto directory = false; auto directory = false;
@ -185,8 +184,8 @@ auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st,
struct fuse_file_info * /*f_info*/) struct fuse_file_info * /*f_info*/)
-> api_error { -> api_error {
#else #else
auto remote_fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st) auto remote_fuse_drive::getattr_impl(std::string api_path,
-> api_error { struct stat *unix_st) -> api_error {
#endif #endif
bool directory = false; bool directory = false;
remote::stat r_stat{}; remote::stat r_stat{};
@ -264,14 +263,14 @@ auto remote_fuse_drive::init_impl(struct fuse_conn_info *conn) -> void * {
server_ = std::make_shared<server>(config_); server_ = std::make_shared<server>(config_);
server_->start(); server_->start();
event_system::instance().raise<drive_mounted>(function_name, event_system::instance().raise<drive_mounted>(function_name,
get_mount_location()); get_mount_location());
} }
return ret; return ret;
} }
auto remote_fuse_drive::mkdir_impl(std::string api_path, mode_t mode) auto remote_fuse_drive::mkdir_impl(std::string api_path,
-> api_error { mode_t mode) -> api_error {
return utils::to_api_error(remote_instance_->fuse_mkdir( return utils::to_api_error(remote_instance_->fuse_mkdir(
api_path.c_str(), static_cast<remote::file_mode>(mode))); api_path.c_str(), static_cast<remote::file_mode>(mode)));
} }
@ -296,9 +295,8 @@ auto remote_fuse_drive::open_impl(std::string api_path,
f_info->fh)); f_info->fh));
} }
auto remote_fuse_drive::opendir_impl(std::string api_path, auto remote_fuse_drive::opendir_impl(
struct fuse_file_info *f_info) std::string api_path, struct fuse_file_info *f_info) -> api_error {
-> api_error {
if ((f_info->flags & O_APPEND) == O_APPEND || if ((f_info->flags & O_APPEND) == O_APPEND ||
(f_info->flags & O_EXCL) == O_EXCL) { (f_info->flags & O_EXCL) == O_EXCL) {
return api_error::directory_exists; return api_error::directory_exists;
@ -311,14 +309,12 @@ auto remote_fuse_drive::opendir_impl(std::string api_path,
void remote_fuse_drive::populate_stat(const remote::stat &r_stat, void remote_fuse_drive::populate_stat(const remote::stat &r_stat,
bool directory, struct stat &unix_st) { bool directory, struct stat &unix_st) {
std::memset(&unix_st, 0, sizeof(struct stat)); std::memset(&unix_st, 0, sizeof(struct stat));
unix_st.st_blksize = unix_st.st_blksize = r_stat.st_blksize;
static_cast<decltype(unix_st.st_blksize)>(r_stat.st_blksize); unix_st.st_blocks = static_cast<blkcnt_t>(r_stat.st_blocks);
unix_st.st_blocks =
static_cast<decltype(unix_st.st_blocks)>(r_stat.st_blocks);
unix_st.st_gid = r_stat.st_gid; unix_st.st_gid = r_stat.st_gid;
unix_st.st_mode = (directory ? S_IFDIR : S_IFREG) | r_stat.st_mode; unix_st.st_mode = (directory ? S_IFDIR : S_IFREG) | r_stat.st_mode;
unix_st.st_nlink = r_stat.st_nlink; unix_st.st_nlink = r_stat.st_nlink;
unix_st.st_size = static_cast<decltype(unix_st.st_size)>(r_stat.st_size); unix_st.st_size = static_cast<off_t>(r_stat.st_size);
unix_st.st_uid = r_stat.st_uid; unix_st.st_uid = r_stat.st_uid;
#if defined(__APPLE__) #if defined(__APPLE__)
@ -377,18 +373,14 @@ auto remote_fuse_drive::read_impl(std::string api_path, char *buffer,
} }
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf, auto remote_fuse_drive::readdir_impl(
fuse_fill_dir_t fuse_fill_dir, std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir,
off_t offset, off_t offset, struct fuse_file_info *f_info,
struct fuse_file_info *f_info, fuse_readdir_flags /*flags*/) -> api_error {
fuse_readdir_flags /*flags*/)
-> api_error {
#else #else
auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf, auto remote_fuse_drive::readdir_impl(
fuse_fill_dir_t fuse_fill_dir, std::string api_path, void *buf, fuse_fill_dir_t fuse_fill_dir,
off_t offset, off_t offset, struct fuse_file_info *f_info) -> api_error {
struct fuse_file_info *f_info)
-> api_error {
#endif #endif
std::string item_path; std::string item_path;
int res = 0; int res = 0;
@ -416,16 +408,14 @@ auto remote_fuse_drive::readdir_impl(std::string api_path, void *buf,
return utils::to_api_error(res); return utils::to_api_error(res);
} }
auto remote_fuse_drive::release_impl(std::string api_path, auto remote_fuse_drive::release_impl(
struct fuse_file_info *f_info) std::string api_path, struct fuse_file_info *f_info) -> api_error {
-> api_error {
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_release(api_path.c_str(), f_info->fh)); remote_instance_->fuse_release(api_path.c_str(), f_info->fh));
} }
auto remote_fuse_drive::releasedir_impl(std::string api_path, auto remote_fuse_drive::releasedir_impl(
struct fuse_file_info *f_info) std::string api_path, struct fuse_file_info *f_info) -> api_error {
-> api_error {
return utils::to_api_error( return utils::to_api_error(
remote_instance_->fuse_releasedir(api_path.c_str(), f_info->fh)); remote_instance_->fuse_releasedir(api_path.c_str(), f_info->fh));
} }
@ -522,8 +512,8 @@ api_error remote_fuse_drive::statfs_x_impl(std::string api_path,
return utils::to_api_error(res); return utils::to_api_error(res);
} }
#else // __APPLE__ #else // __APPLE__
auto remote_fuse_drive::statfs_impl(std::string api_path, struct statvfs *stbuf) auto remote_fuse_drive::statfs_impl(std::string api_path,
-> api_error { struct statvfs *stbuf) -> api_error {
auto res = statvfs(config_.get_data_directory().c_str(), stbuf); auto res = statvfs(config_.get_data_directory().c_str(), stbuf);
if (res == 0) { if (res == 0) {
remote::statfs r_stat{}; remote::statfs r_stat{};
@ -550,8 +540,8 @@ auto remote_fuse_drive::truncate_impl(std::string api_path, off_t size,
struct fuse_file_info * /*f_info*/) struct fuse_file_info * /*f_info*/)
-> api_error { -> api_error {
#else #else
auto remote_fuse_drive::truncate_impl(std::string api_path, off_t size) auto remote_fuse_drive::truncate_impl(std::string api_path,
-> api_error { off_t size) -> api_error {
#endif #endif
return utils::to_api_error(remote_instance_->fuse_truncate( return utils::to_api_error(remote_instance_->fuse_truncate(
api_path.c_str(), static_cast<remote::file_offset>(size))); api_path.c_str(), static_cast<remote::file_offset>(size)));
@ -562,10 +552,9 @@ auto remote_fuse_drive::unlink_impl(std::string api_path) -> api_error {
} }
#if FUSE_USE_VERSION >= 30 #if FUSE_USE_VERSION >= 30
auto remote_fuse_drive::utimens_impl(std::string api_path, auto remote_fuse_drive::utimens_impl(
const struct timespec tv[2], std::string api_path, const struct timespec tv[2],
struct fuse_file_info * /*f_info*/) struct fuse_file_info * /*f_info*/) -> api_error {
-> api_error {
#else #else
auto remote_fuse_drive::utimens_impl(std::string api_path, auto remote_fuse_drive::utimens_impl(std::string api_path,
const struct timespec tv[2]) -> api_error { const struct timespec tv[2]) -> api_error {

View File

@ -22,11 +22,13 @@
#include "drives/winfsp/remotewinfsp/remote_client.hpp" #include "drives/winfsp/remotewinfsp/remote_client.hpp"
#include "app_config.hpp" #include "app_config.hpp"
#include "drives/winfsp/remotewinfsp/i_remote_instance.hpp"
#include "events/event_system.hpp" #include "events/event_system.hpp"
#include "events/types/drive_mounted.hpp" #include "events/types/drive_mounted.hpp"
#include "events/types/drive_unmount_pending.hpp" #include "events/types/drive_unmount_pending.hpp"
#include "events/types/drive_unmounted.hpp" #include "events/types/drive_unmounted.hpp"
#include "utils/string.hpp" #include "types/repertory.hpp"
#include "utils/path.hpp"
#include "version.hpp" #include "version.hpp"
namespace repertory::remote_winfsp { namespace repertory::remote_winfsp {
@ -42,7 +44,11 @@ auto remote_client::winfsp_can_delete(PVOID file_desc, PWSTR file_name)
request.encode(file_name); request.encode(file_name);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags); auto ret{
packet_client_.send(function_name, request, service_flags),
};
return ret;
} }
auto remote_client::json_create_directory_snapshot(const std::string &path, auto remote_client::json_create_directory_snapshot(const std::string &path,
@ -97,7 +103,11 @@ auto remote_client::json_release_directory_snapshot(
request.encode(handle); request.encode(handle);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags); auto ret{
packet_client_.send(function_name, request, service_flags),
};
return ret;
} }
auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name, auto remote_client::winfsp_cleanup(PVOID file_desc, PWSTR file_name,
@ -263,8 +273,8 @@ auto remote_client::winfsp_get_security_by_name(PWSTR file_name,
packet request; packet request;
request.encode(file_name); request.encode(file_name);
request.encode(descriptor_size == nullptr ? std::uint64_t(0U) request.encode(static_cast<std::uint64_t>(
: *descriptor_size); descriptor_size == nullptr ? 0 : *descriptor_size));
request.encode(static_cast<std::uint8_t>(attributes != nullptr)); request.encode(static_cast<std::uint8_t>(attributes != nullptr));
packet response; packet response;
@ -407,7 +417,7 @@ auto remote_client::winfsp_read(PVOID file_desc, PVOID buffer, UINT64 offset,
ret = response.decode(buffer, *bytes_transferred); ret = response.decode(buffer, *bytes_transferred);
#if defined(_WIN32) #if defined(_WIN32)
if ((ret == STATUS_SUCCESS) && if ((ret == STATUS_SUCCESS) &&
((*bytes_transferred == 0U) || (*bytes_transferred != length))) { (not*bytes_transferred || (*bytes_transferred != length))) {
::SetLastError(ERROR_HANDLE_EOF); ::SetLastError(ERROR_HANDLE_EOF);
} }
#endif #endif
@ -451,7 +461,11 @@ auto remote_client::winfsp_rename(PVOID file_desc, PWSTR file_name,
request.encode(replace_if_exists); request.encode(replace_if_exists);
std::uint32_t service_flags{}; std::uint32_t service_flags{};
return packet_client_.send(function_name, request, service_flags); auto ret{
packet_client_.send(function_name, request, service_flags),
};
return ret;
} }
auto remote_client::winfsp_set_basic_info( auto remote_client::winfsp_set_basic_info(

View File

@ -466,13 +466,6 @@ auto file_manager::open(const std::string &api_path, bool directory,
return download_type::default_; return download_type::default_;
} }
if (utils::file::file{fsi.source_path}.exists()) {
auto size = utils::file::file{fsi.source_path}.size();
if (size.has_value() && *size == fsi.size) {
return download_type::default_;
}
}
if (type == download_type::direct) { if (type == download_type::direct) {
return type; return type;
} }

View File

@ -98,23 +98,19 @@ auto ring_buffer_base::close() -> bool {
return res; return res;
} }
auto ring_buffer_base::download_chunk(std::size_t chunk, bool skip_active) auto ring_buffer_base::download_chunk(std::size_t chunk,
-> api_error { bool skip_active) -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
unique_mutex_lock chunk_lock(chunk_mtx_); unique_mutex_lock chunk_lock(chunk_mtx_);
if (not skip_active) { const auto unlock_and_notify = [this, &chunk_lock]() {
ring_pos_ = chunk;
}
const auto notify_and_unlock = [this, &chunk_lock]() {
chunk_notify_.notify_all(); chunk_notify_.notify_all();
chunk_lock.unlock(); chunk_lock.unlock();
}; };
const auto unlock_and_return = const auto unlock_and_return =
[&notify_and_unlock](api_error res) -> api_error { [&unlock_and_notify](api_error res) -> api_error {
notify_and_unlock(); unlock_and_notify();
return res; return res;
}; };
@ -128,7 +124,7 @@ auto ring_buffer_base::download_chunk(std::size_t chunk, bool skip_active)
} }
auto active_download = get_active_downloads().at(chunk); auto active_download = get_active_downloads().at(chunk);
notify_and_unlock(); unlock_and_notify();
return active_download->wait(); return active_download->wait();
} }
@ -146,7 +142,7 @@ auto ring_buffer_base::download_chunk(std::size_t chunk, bool skip_active)
chunk == (total_chunks_ - 1U) ? get_last_chunk_size() chunk == (total_chunks_ - 1U) ? get_last_chunk_size()
: get_chunk_size(), : get_chunk_size(),
}; };
notify_and_unlock(); unlock_and_notify();
auto result{ auto result{
get_provider().read_file_bytes(get_api_path(), data_size, data_offset, get_provider().read_file_bytes(get_api_path(), data_size, data_offset,
@ -171,7 +167,7 @@ auto ring_buffer_base::download_chunk(std::size_t chunk, bool skip_active)
} }
get_active_downloads().erase(chunk); get_active_downloads().erase(chunk);
notify_and_unlock(); unlock_and_notify();
active_download->notify(result); active_download->notify(result);
return result; return result;
@ -230,6 +226,7 @@ auto ring_buffer_base::read(std::size_t read_size, std::uint64_t read_offset,
} else if (chunk < ring_pos_) { } else if (chunk < ring_pos_) {
reverse(ring_pos_ - chunk); reverse(ring_pos_ - chunk);
} }
res = download_chunk(chunk, false); res = download_chunk(chunk, false);
if (res != api_error::success) { if (res != api_error::success) {
if (res == api_error::invalid_ring_buffer_position) { if (res == api_error::invalid_ring_buffer_position) {
@ -267,46 +264,38 @@ void ring_buffer_base::reader_thread() {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
unique_mutex_lock chunk_lock(chunk_mtx_); unique_mutex_lock chunk_lock(chunk_mtx_);
const auto notify_and_unlock = [this, &chunk_lock]() { auto next_chunk{ring_pos_};
chunk_notify_.notify_all(); chunk_notify_.notify_all();
chunk_lock.unlock(); chunk_lock.unlock();
};
auto last_pos = ring_pos_;
auto next_chunk = ring_pos_;
notify_and_unlock();
while (not get_stop_requested()) { while (not get_stop_requested()) {
chunk_lock.lock(); chunk_lock.lock();
if (last_pos == ring_pos_) { next_chunk = next_chunk + 1U > ring_end_ ? ring_begin_ : next_chunk + 1U;
++next_chunk; const auto check_and_wait = [this, &chunk_lock, &next_chunk]() {
} else {
next_chunk = ring_pos_ + 1U;
last_pos = ring_pos_;
}
if (next_chunk > ring_end_) {
next_chunk = ring_begin_;
}
if (read_state_[next_chunk % read_state_.size()]) {
if (get_stop_requested()) { if (get_stop_requested()) {
notify_and_unlock(); chunk_notify_.notify_all();
chunk_lock.unlock();
return; return;
} }
if (get_read_state().all()) { if (get_read_state().all()) {
chunk_notify_.wait(chunk_lock); chunk_notify_.wait(chunk_lock);
last_pos = ring_pos_;
next_chunk = ring_pos_; next_chunk = ring_pos_;
} }
notify_and_unlock(); chunk_notify_.notify_all();
chunk_lock.unlock();
};
if (read_state_[next_chunk % read_state_.size()]) {
check_and_wait();
continue; continue;
} }
notify_and_unlock(); chunk_notify_.notify_all();
chunk_lock.unlock();
download_chunk(next_chunk, true); download_chunk(next_chunk, true);
} }
@ -362,30 +351,29 @@ void ring_buffer_base::update_position(std::size_t count, bool is_forward) {
if (is_forward ? (ring_pos_ + count) <= ring_end_ if (is_forward ? (ring_pos_ + count) <= ring_end_
: (ring_pos_ - count) >= ring_begin_) { : (ring_pos_ - count) >= ring_begin_) {
ring_pos_ += is_forward ? count : -count; ring_pos_ += is_forward ? count : -count;
chunk_notify_.notify_all();
return;
}
auto delta = is_forward ? count - (ring_end_ - ring_pos_)
: count - (ring_pos_ - ring_begin_);
if (delta >= read_state_.size()) {
read_state_.set(0U, read_state_.size(), false);
ring_pos_ += is_forward ? count : -count;
ring_begin_ += is_forward ? delta : -delta;
} else { } else {
for (std::size_t idx = 0U; idx < delta; ++idx) { auto delta = is_forward ? count - (ring_end_ - ring_pos_)
if (is_forward) { : count - (ring_pos_ - ring_begin_);
read_state_[(ring_begin_ + idx) % read_state_.size()] = false;
} else {
read_state_[(ring_end_ - idx) % read_state_.size()] = false;
}
}
ring_begin_ += is_forward ? delta : -delta;
ring_pos_ += is_forward ? count : -count;
}
ring_end_ = if (delta >= read_state_.size()) {
std::min(total_chunks_ - 1U, ring_begin_ + read_state_.size() - 1U); read_state_.set(0U, read_state_.size(), false);
ring_pos_ += is_forward ? count : -count;
ring_begin_ += is_forward ? delta : -delta;
} else {
for (std::size_t idx = 0U; idx < delta; ++idx) {
if (is_forward) {
read_state_[(ring_begin_ + idx) % read_state_.size()] = false;
} else {
read_state_[(ring_end_ - idx) % read_state_.size()] = false;
}
}
ring_begin_ += is_forward ? delta : -delta;
ring_pos_ += is_forward ? count : -count;
}
ring_end_ =
std::min(total_chunks_ - 1U, ring_begin_ + read_state_.size() - 1U);
}
chunk_notify_.notify_all(); chunk_notify_.notify_all();
} }

View File

@ -50,6 +50,10 @@
namespace repertory { namespace repertory {
auto project_initialize() -> bool { auto project_initialize() -> bool {
spdlog::drop_all();
spdlog::flush_every(std::chrono::seconds(10));
spdlog::set_pattern("%Y-%m-%d|%T.%e|%^%l%$|%v");
#if defined(PROJECT_REQUIRE_ALPINE) && !defined(PROJECT_IS_MINGW) #if defined(PROJECT_REQUIRE_ALPINE) && !defined(PROJECT_IS_MINGW)
{ {
static constexpr const auto guard_size{4096U}; static constexpr const auto guard_size{4096U};
@ -64,10 +68,6 @@ auto project_initialize() -> bool {
} }
#endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW) #endif // defined(PROJECT_REQUIRE_ALPINE) && !defined (PROJECT_IS_MINGW)
spdlog::drop_all();
spdlog::flush_every(std::chrono::seconds(10));
spdlog::set_pattern("%Y-%m-%d|%T.%e|%^%l%$|%v");
#if defined(PROJECT_ENABLE_LIBSODIUM) #if defined(PROJECT_ENABLE_LIBSODIUM)
{ {
if (sodium_init() == -1) { if (sodium_init() == -1) {
@ -77,9 +77,7 @@ auto project_initialize() -> bool {
#endif // defined(PROJECT_ENABLE_LIBSODIUM) #endif // defined(PROJECT_ENABLE_LIBSODIUM)
#if defined(PROJECT_ENABLE_OPENSSL) #if defined(PROJECT_ENABLE_OPENSSL)
{ { SSL_library_init(); }
SSL_library_init();
}
#endif // defined(PROJECT_ENABLE_OPENSSL) #endif // defined(PROJECT_ENABLE_OPENSSL)
#if defined(PROJECT_ENABLE_CURL) #if defined(PROJECT_ENABLE_CURL)

View File

@ -34,7 +34,6 @@
#include "events/types/orphaned_file_processing_failed.hpp" #include "events/types/orphaned_file_processing_failed.hpp"
#include "events/types/orphaned_source_file_detected.hpp" #include "events/types/orphaned_source_file_detected.hpp"
#include "events/types/orphaned_source_file_removed.hpp" #include "events/types/orphaned_source_file_removed.hpp"
#include "events/types/provider_invalid_version.hpp"
#include "events/types/provider_offline.hpp" #include "events/types/provider_offline.hpp"
#include "events/types/provider_upload_begin.hpp" #include "events/types/provider_upload_begin.hpp"
#include "events/types/provider_upload_end.hpp" #include "events/types/provider_upload_end.hpp"
@ -70,8 +69,8 @@ void base_provider::add_all_items(stop_type &stop_requested) {
} }
auto base_provider::create_api_file(std::string path, std::string key, auto base_provider::create_api_file(std::string path, std::string key,
std::uint64_t size, std::uint64_t file_time) std::uint64_t size,
-> api_file { std::uint64_t file_time) -> api_file {
api_file file{}; api_file file{};
file.api_path = utils::path::create_api_path(path); file.api_path = utils::path::create_api_path(path);
file.api_parent = utils::path::get_parent_api_path(file.api_path); file.api_parent = utils::path::get_parent_api_path(file.api_path);
@ -103,8 +102,8 @@ auto base_provider::create_api_file(std::string path, std::uint64_t size,
} }
auto base_provider::create_directory_clone_source_meta( auto base_provider::create_directory_clone_source_meta(
const std::string &source_api_path, const std::string &api_path) const std::string &source_api_path,
-> api_error { const std::string &api_path) -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
bool exists{}; bool exists{};
@ -202,8 +201,8 @@ auto base_provider::create_directory(const std::string &api_path,
return api_error::error; return api_error::error;
} }
auto base_provider::create_file(const std::string &api_path, api_meta_map &meta) auto base_provider::create_file(const std::string &api_path,
-> api_error { api_meta_map &meta) -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -260,9 +259,8 @@ auto base_provider::create_file(const std::string &api_path, api_meta_map &meta)
return api_error::error; return api_error::error;
} }
auto base_provider::get_api_path_from_source(const std::string &source_path, auto base_provider::get_api_path_from_source(
std::string &api_path) const const std::string &source_path, std::string &api_path) const -> api_error {
-> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
if (source_path.empty()) { if (source_path.empty()) {
@ -275,9 +273,8 @@ auto base_provider::get_api_path_from_source(const std::string &source_path,
return db3_->get_api_path(source_path, api_path); return db3_->get_api_path(source_path, api_path);
} }
auto base_provider::get_directory_items(const std::string &api_path, auto base_provider::get_directory_items(
directory_item_list &list) const const std::string &api_path, directory_item_list &list) const -> api_error {
-> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -286,15 +283,8 @@ auto base_provider::get_directory_items(const std::string &api_path,
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
} }
if (not exists) { if (not exists) {
res = is_file(api_path, exists); return api_error::directory_not_found;
if (res != api_error::success) {
utils::error::raise_api_path_error(
function_name, api_path, res, "failed to determine if file exists");
}
return exists ? api_error::item_exists : api_error::directory_not_found;
} }
res = get_directory_items_impl(api_path, list); res = get_directory_items_impl(api_path, list);
@ -352,10 +342,9 @@ auto base_provider::get_file_size(const std::string &api_path,
return api_error::success; return api_error::success;
} }
auto base_provider::get_filesystem_item(const std::string &api_path, auto base_provider::get_filesystem_item(
bool directory, const std::string &api_path, bool directory,
filesystem_item &fsi) const filesystem_item &fsi) const -> api_error {
-> api_error {
bool exists{}; bool exists{};
auto res = is_directory(api_path, exists); auto res = is_directory(api_path, exists);
if (res != api_error::success) { if (res != api_error::success) {
@ -388,10 +377,9 @@ auto base_provider::get_filesystem_item(const std::string &api_path,
return api_error::success; return api_error::success;
} }
auto base_provider::get_filesystem_item_and_file(const std::string &api_path, auto base_provider::get_filesystem_item_and_file(
api_file &file, const std::string &api_path, api_file &file,
filesystem_item &fsi) const filesystem_item &fsi) const -> api_error {
-> api_error {
auto res = get_file(api_path, file); auto res = get_file(api_path, file);
if (res != api_error::success) { if (res != api_error::success) {
return res; return res;
@ -841,14 +829,6 @@ auto base_provider::start(api_item_added_callback api_item_added,
return false; return false;
} }
std::string returned_version;
std::string required_version;
if (not check_version(required_version, returned_version)) {
event_system::instance().raise<provider_invalid_version>(
function_name, required_version, returned_version);
return false;
}
cache_size_mgr::instance().initialize(&config_); cache_size_mgr::instance().initialize(&config_);
polling::instance().set_callback({ polling::instance().set_callback({

View File

@ -40,7 +40,6 @@
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include <spdlog/fmt/bundled/base.h>
namespace repertory { namespace repertory {
encrypt_provider::encrypt_provider(app_config &config) encrypt_provider::encrypt_provider(app_config &config)
@ -263,6 +262,7 @@ auto encrypt_provider::get_directory_items(const std::string &api_path,
dir_item.api_parent = file.api_parent; dir_item.api_parent = file.api_parent;
dir_item.api_path = file.api_path; dir_item.api_path = file.api_path;
dir_item.directory = dir_entry->is_directory_item(); dir_item.directory = dir_entry->is_directory_item();
dir_item.resolved = true;
dir_item.size = file.file_size; dir_item.size = file.file_size;
create_item_meta(dir_item.meta, dir_item.directory, file); create_item_meta(dir_item.meta, dir_item.directory, file);
@ -342,23 +342,13 @@ auto encrypt_provider::get_file_list(api_file_list &list,
const auto &cfg{get_encrypt_config()}; const auto &cfg{get_encrypt_config()};
try { try {
using func = std::function<void(std::string path)>; for (const auto &dir_entry : utils::file::directory{cfg.path}.get_items()) {
const func process_directory = [&](std::string path) { std::string api_path{};
for (const auto &dir_entry : utils::file::directory{path}.get_items()) { if (process_directory_entry(*dir_entry.get(), cfg, api_path)) {
std::string api_path{}; list.emplace_back(create_api_file(
if (dir_entry->is_directory_item()) { api_path, dir_entry->is_directory_item(), dir_entry->get_path()));
process_directory_entry(*dir_entry.get(), cfg, api_path);
process_directory(dir_entry->get_path());
continue;
}
if (process_directory_entry(*dir_entry.get(), cfg, api_path)) {
list.emplace_back(create_api_file(
api_path, dir_entry->is_directory_item(), dir_entry->get_path()));
}
} }
}; }
process_directory(cfg.path);
return api_error::success; return api_error::success;
} catch (const std::exception &ex) { } catch (const std::exception &ex) {

View File

@ -43,9 +43,9 @@
#include "utils/time.hpp" #include "utils/time.hpp"
namespace { namespace {
[[nodiscard]] auto set_request_path(auto &request, [[nodiscard]] auto
const std::string &object_name) set_request_path(auto &request,
-> repertory::api_error { const std::string &object_name) -> repertory::api_error {
request.path = object_name; request.path = object_name;
if (request.path.substr(1U).size() > repertory::max_s3_object_name_length) { if (request.path.substr(1U).size() > repertory::max_s3_object_name_length) {
return repertory::api_error::name_too_long; return repertory::api_error::name_too_long;
@ -59,9 +59,8 @@ namespace repertory {
s3_provider::s3_provider(app_config &config, i_http_comm &comm) s3_provider::s3_provider(app_config &config, i_http_comm &comm)
: base_provider(config, comm) {} : base_provider(config, comm) {}
auto s3_provider::add_if_not_found(api_file &file, auto s3_provider::add_if_not_found(
const std::string &object_name) const api_file &file, const std::string &object_name) const -> api_error {
-> api_error {
api_meta_map meta{}; api_meta_map meta{};
auto res{get_item_meta(file.api_path, meta)}; auto res{get_item_meta(file.api_path, meta)};
if (res == api_error::item_not_found) { if (res == api_error::item_not_found) {
@ -89,7 +88,7 @@ auto s3_provider::convert_api_date(std::string_view date) -> std::uint64_t {
1000000UL, 1000000UL,
}; };
struct tm tm1{}; struct tm tm1 {};
#if defined(_WIN32) #if defined(_WIN32)
utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1); utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
return nanos + utils::time::windows_time_t_to_unix_time(_mkgmtime(&tm1)); return nanos + utils::time::windows_time_t_to_unix_time(_mkgmtime(&tm1));
@ -158,9 +157,8 @@ auto s3_provider::create_directory_impl(const std::string &api_path,
utils::path::create_api_path(is_encrypted ? meta[META_KEY] : api_path)); utils::path::create_api_path(is_encrypted ? meta[META_KEY] : api_path));
} }
auto s3_provider::create_directory_paths(const std::string &api_path, auto s3_provider::create_directory_paths(
const std::string &key) const const std::string &api_path, const std::string &key) const -> api_error {
-> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
if (api_path == "/") { if (api_path == "/") {
@ -323,9 +321,8 @@ auto s3_provider::get_directory_item_count(const std::string &api_path) const
return 0U; return 0U;
} }
auto s3_provider::get_directory_items_impl(const std::string &api_path, auto s3_provider::get_directory_items_impl(
directory_item_list &list) const const std::string &api_path, directory_item_list &list) const -> api_error {
-> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
const auto &cfg{get_s3_config()}; const auto &cfg{get_s3_config()};
@ -483,8 +480,8 @@ auto s3_provider::get_directory_items_impl(const std::string &api_path,
return api_error::success; return api_error::success;
} }
auto s3_provider::get_file(const std::string &api_path, api_file &file) const auto s3_provider::get_file(const std::string &api_path,
-> api_error { api_file &file) const -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -495,19 +492,7 @@ auto s3_provider::get_file(const std::string &api_path, api_file &file) const
get_object_info(false, api_path, is_encrypted, object_name, result), get_object_info(false, api_path, is_encrypted, object_name, result),
}; };
if (res != api_error::success) { if (res != api_error::success) {
if (res != api_error::item_not_found) { return res;
return res;
}
bool exists{};
res = is_directory(api_path, exists);
if (res != api_error::success) {
utils::error::raise_api_path_error(
function_name, api_path, res,
"failed to determine if directory exists");
}
return exists ? api_error::directory_exists : api_error::item_not_found;
} }
file.api_path = api_path; file.api_path = api_path;
@ -536,8 +521,8 @@ auto s3_provider::get_file(const std::string &api_path, api_file &file) const
return api_error::error; return api_error::error;
} }
auto s3_provider::get_file_list(api_file_list &list, std::string &marker) const auto s3_provider::get_file_list(api_file_list &list,
-> api_error { std::string &marker) const -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -627,9 +612,8 @@ auto s3_provider::get_file_list(api_file_list &list, std::string &marker) const
return api_error::error; return api_error::error;
} }
auto s3_provider::get_last_modified(bool directory, auto s3_provider::get_last_modified(
const std::string &api_path) const bool directory, const std::string &api_path) const -> std::uint64_t {
-> std::uint64_t {
bool is_encrypted{}; bool is_encrypted{};
std::string object_name; std::string object_name;
head_object_result result{}; head_object_result result{};
@ -639,10 +623,9 @@ auto s3_provider::get_last_modified(bool directory,
: utils::time::get_time_now(); : utils::time::get_time_now();
} }
auto s3_provider::get_object_info(bool directory, const std::string &api_path, auto s3_provider::get_object_info(
bool &is_encrypted, std::string &object_name, bool directory, const std::string &api_path, bool &is_encrypted,
head_object_result &result) const std::string &object_name, head_object_result &result) const -> api_error {
-> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -702,12 +685,10 @@ auto s3_provider::get_object_info(bool directory, const std::string &api_path,
return api_error::error; return api_error::error;
} }
auto s3_provider::get_object_list(std::string &response_data, auto s3_provider::get_object_list(
long &response_code, std::string &response_data, long &response_code,
std::optional<std::string> delimiter, std::optional<std::string> delimiter, std::optional<std::string> prefix,
std::optional<std::string> prefix, std::optional<std::string> token) const -> bool {
std::optional<std::string> token) const
-> bool {
curl::requests::http_get get{}; curl::requests::http_get get{};
get.allow_timeout = true; get.allow_timeout = true;
get.aws_service = "aws:amz:" + get_s3_config().region + ":s3"; get.aws_service = "aws:amz:" + get_s3_config().region + ":s3";
@ -735,8 +716,8 @@ auto s3_provider::get_total_drive_space() const -> std::uint64_t {
return std::numeric_limits<std::int64_t>::max() / std::int64_t(2); return std::numeric_limits<std::int64_t>::max() / std::int64_t(2);
} }
auto s3_provider::is_directory(const std::string &api_path, bool &exists) const auto s3_provider::is_directory(const std::string &api_path,
-> api_error { bool &exists) const -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -764,8 +745,8 @@ auto s3_provider::is_directory(const std::string &api_path, bool &exists) const
return api_error::error; return api_error::error;
} }
auto s3_provider::is_file(const std::string &api_path, bool &exists) const auto s3_provider::is_file(const std::string &api_path,
-> api_error { bool &exists) const -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
try { try {
@ -1023,8 +1004,8 @@ auto s3_provider::rename_file(const std::string & /* from_api_path */,
return api_error::not_implemented; return api_error::not_implemented;
} }
auto s3_provider::set_meta_key(const std::string &api_path, api_meta_map &meta) auto s3_provider::set_meta_key(const std::string &api_path,
-> api_error { api_meta_map &meta) -> api_error {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
const auto &cfg{get_s3_config()}; const auto &cfg{get_s3_config()};

View File

@ -32,8 +32,8 @@
#include "providers/base_provider.hpp" #include "providers/base_provider.hpp"
#include "providers/s3/s3_provider.hpp" #include "providers/s3/s3_provider.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/common.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
@ -63,54 +63,6 @@ namespace repertory {
sia_provider::sia_provider(app_config &config, i_http_comm &comm) sia_provider::sia_provider(app_config &config, i_http_comm &comm)
: base_provider(config, comm) {} : base_provider(config, comm) {}
auto sia_provider::check_version(std::string &required_version,
std::string &returned_version) const -> bool {
REPERTORY_USES_FUNCTION_NAME();
required_version = "2.0.0";
try {
curl::requests::http_get get{};
get.allow_timeout = true;
get.path = "/api/bus/state";
nlohmann::json state_data;
std::string error_data;
get.response_handler = [&error_data, &state_data](auto &&data,
long response_code) {
if (response_code == http_error_codes::ok) {
state_data = nlohmann::json::parse(data.begin(), data.end());
return;
}
error_data = std::string(data.begin(), data.end());
};
long response_code{};
stop_type stop_requested{};
if (not get_comm().make_request(get, response_code, stop_requested)) {
utils::error::raise_error(function_name, response_code,
"failed to check state");
return false;
}
if (response_code != http_error_codes::ok) {
utils::error::raise_error(
function_name, response_code,
fmt::format("failed to check state|response|{}", error_data));
return false;
}
returned_version = state_data.at("version").get<std::string>().substr(1U);
return utils::compare_version_strings(returned_version, required_version) >=
0;
} catch (const std::exception &e) {
utils::error::raise_error(function_name, e, "failed to check version");
}
return false;
}
auto sia_provider::create_directory_impl(const std::string &api_path, auto sia_provider::create_directory_impl(const std::string &api_path,
api_meta_map & /* meta */) api_meta_map & /* meta */)
-> api_error { -> api_error {
@ -118,7 +70,7 @@ auto sia_provider::create_directory_impl(const std::string &api_path,
curl::requests::http_put_file put_file{}; curl::requests::http_put_file put_file{};
put_file.allow_timeout = true; put_file.allow_timeout = true;
put_file.path = "/api/worker/object" + api_path + "/"; put_file.path = "/api/worker/objects" + api_path + "/";
put_file.query["bucket"] = get_bucket(get_sia_config()); put_file.query["bucket"] = get_bucket(get_sia_config());
std::string error_data; std::string error_data;
@ -160,10 +112,10 @@ auto sia_provider::get_directory_item_count(const std::string &api_path) const
} }
std::uint64_t item_count{}; std::uint64_t item_count{};
if (object_list.contains("objects")) { if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("objects")) { for (const auto &entry : object_list.at("entries")) {
try { try {
auto name{entry.at("key").get<std::string>()}; auto name{entry.at("name").get<std::string>()};
auto entry_api_path{utils::path::create_api_path(name)}; auto entry_api_path{utils::path::create_api_path(name)};
if (utils::string::ends_with(name, "/") && if (utils::string::ends_with(name, "/") &&
(entry_api_path == api_path)) { (entry_api_path == api_path)) {
@ -197,10 +149,10 @@ auto sia_provider::get_directory_items_impl(const std::string &api_path,
return api_error::comm_error; return api_error::comm_error;
} }
if (object_list.contains("objects")) { if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("objects")) { for (const auto &entry : object_list.at("entries")) {
try { try {
auto name{entry.at("key").get<std::string>()}; auto name{entry.at("name").get<std::string>()};
auto entry_api_path{utils::path::create_api_path(name)}; auto entry_api_path{utils::path::create_api_path(name)};
auto directory{utils::string::ends_with(name, "/")}; auto directory{utils::string::ends_with(name, "/")};
@ -233,6 +185,7 @@ auto sia_provider::get_directory_items_impl(const std::string &api_path,
dir_item.api_path = file.api_path; dir_item.api_path = file.api_path;
dir_item.directory = directory; dir_item.directory = directory;
dir_item.meta = meta; dir_item.meta = meta;
dir_item.resolved = true;
dir_item.size = file.file_size; dir_item.size = file.file_size;
list.emplace_back(std::move(dir_item)); list.emplace_back(std::move(dir_item));
} catch (const std::exception &e) { } catch (const std::exception &e) {
@ -254,28 +207,22 @@ auto sia_provider::get_file(const std::string &api_path, api_file &file) const
json file_data{}; json file_data{};
auto res{get_object_info(api_path, file_data)}; auto res{get_object_info(api_path, file_data)};
if (res != api_error::success) { if (res != api_error::success) {
if (res != api_error::item_not_found) { return res;
return res;
}
bool exists{};
res = is_directory(api_path, exists);
if (res != api_error::success) {
utils::error::raise_api_path_error(
function_name, api_path, res,
"failed to determine if directory exists");
}
return exists ? api_error::directory_exists : api_error::item_not_found;
} }
auto slabs{file_data["object"]["Slabs"]};
auto size{ auto size{
file_data.at("size").get<std::uint64_t>(), std::accumulate(
slabs.begin(), slabs.end(), std::uint64_t(0U),
[](auto &&total_size, const json &slab) -> std::uint64_t {
return total_size + slab["Length"].get<std::uint64_t>();
}),
}; };
api_meta_map meta{}; api_meta_map meta{};
if (get_item_meta(api_path, meta) == api_error::item_not_found) { if (get_item_meta(api_path, meta) == api_error::item_not_found) {
file = create_api_file(api_path, "", size, get_last_modified(file_data)); file = create_api_file(api_path, "", size,
get_last_modified(file_data["object"]));
get_api_item_added()(false, file); get_api_item_added()(false, file);
} else { } else {
file = create_api_file(api_path, size, meta); file = create_api_file(api_path, size, meta);
@ -303,9 +250,9 @@ auto sia_provider::get_file_list(api_file_list &list,
return api_error::comm_error; return api_error::comm_error;
} }
if (object_list.contains("objects")) { if (object_list.contains("entries")) {
for (const auto &entry : object_list.at("objects")) { for (const auto &entry : object_list.at("entries")) {
auto name{entry.at("key").get<std::string>()}; auto name{entry.at("name").get<std::string>()};
auto entry_api_path{utils::path::create_api_path(name)}; auto entry_api_path{utils::path::create_api_path(name)};
if (utils::string::ends_with(name, "/")) { if (utils::string::ends_with(name, "/")) {
@ -366,9 +313,8 @@ auto sia_provider::get_object_info(const std::string &api_path,
try { try {
curl::requests::http_get get{}; curl::requests::http_get get{};
get.allow_timeout = true; get.allow_timeout = true;
get.path = "/api/bus/object" + api_path; get.path = "/api/bus/objects" + api_path;
get.query["bucket"] = get_bucket(get_sia_config()); get.query["bucket"] = get_bucket(get_sia_config());
get.query["onlymetadata"] = "true";
std::string error_data; std::string error_data;
get.response_handler = [&error_data, &object_info](auto &&data, get.response_handler = [&error_data, &object_info](auto &&data,
@ -416,7 +362,6 @@ auto sia_provider::get_object_list(const std::string &api_path,
get.allow_timeout = true; get.allow_timeout = true;
get.path = "/api/bus/objects" + api_path + "/"; get.path = "/api/bus/objects" + api_path + "/";
get.query["bucket"] = get_bucket(get_sia_config()); get.query["bucket"] = get_bucket(get_sia_config());
get.query["delimiter"] = "/";
std::string error_data; std::string error_data;
get.response_handler = [&error_data, &object_list](auto &&data, get.response_handler = [&error_data, &object_list](auto &&data,
@ -460,7 +405,7 @@ auto sia_provider::get_total_drive_space() const -> std::uint64_t {
try { try {
curl::requests::http_get get{}; curl::requests::http_get get{};
get.allow_timeout = true; get.allow_timeout = true;
get.path = "/api/bus/autopilot"; get.path = "/api/autopilot/config";
get.query["bucket"] = get_bucket(get_sia_config()); get.query["bucket"] = get_bucket(get_sia_config());
json config_data; json config_data;
@ -510,18 +455,17 @@ auto sia_provider::is_directory(const std::string &api_path, bool &exists) const
exists = false; exists = false;
json file_data{}; json object_list{};
auto res{get_object_info(api_path + '/', file_data)}; if (not get_object_list(utils::path::get_parent_api_path(api_path),
if (res == api_error::item_not_found) { object_list)) {
return api_error::success; return api_error::comm_error;
} }
if (res != api_error::success) { exists = object_list.contains("entries") &&
return res; std::ranges::find_if(object_list.at("entries"),
} [&api_path](auto &&entry) -> bool {
return entry.at("name") == (api_path + "/");
exists = }) != object_list.at("entries").end();
utils::string::ends_with(file_data.at("key").get<std::string>(), "/");
return api_error::success; return api_error::success;
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
@ -537,7 +481,6 @@ auto sia_provider::is_file(const std::string &api_path, bool &exists) const
try { try {
exists = false; exists = false;
if (api_path == "/") { if (api_path == "/") {
return api_error::success; return api_error::success;
} }
@ -552,8 +495,7 @@ auto sia_provider::is_file(const std::string &api_path, bool &exists) const
return res; return res;
} }
exists = not utils::string::ends_with( exists = not file_data.contains("entries");
file_data.at("key").get<std::string>(), "/");
return api_error::success; return api_error::success;
} catch (const std::exception &e) { } catch (const std::exception &e) {
utils::error::raise_api_path_error(function_name, api_path, e, utils::error::raise_api_path_error(function_name, api_path, e,
@ -617,9 +559,8 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
try { try {
curl::requests::http_get get{}; curl::requests::http_get get{};
get.path = "/api/worker/object" + api_path; get.path = "/api/worker/objects" + api_path;
get.query["bucket"] = get_bucket(get_sia_config()); get.query["bucket"] = get_bucket(get_sia_config());
get.headers["accept"] = "application/octet-stream";
get.range = {{ get.range = {{
offset, offset,
offset + size - 1U, offset + size - 1U,
@ -636,7 +577,6 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
++idx) { ++idx) {
long response_code{}; long response_code{};
const auto notify_retry = [&]() { const auto notify_retry = [&]() {
fmt::println("{}", std::string(buffer.begin(), buffer.end()));
if (response_code == 0) { if (response_code == 0) {
utils::error::raise_api_path_error( utils::error::raise_api_path_error(
function_name, api_path, api_error::comm_error, function_name, api_path, api_error::comm_error,
@ -682,7 +622,7 @@ auto sia_provider::remove_directory_impl(const std::string &api_path)
curl::requests::http_delete del{}; curl::requests::http_delete del{};
del.allow_timeout = true; del.allow_timeout = true;
del.path = "/api/bus/object" + api_path + "/"; del.path = "/api/bus/objects" + api_path + "/";
del.query["bucket"] = get_bucket(get_sia_config()); del.query["bucket"] = get_bucket(get_sia_config());
std::string error_data; std::string error_data;
@ -718,7 +658,7 @@ auto sia_provider::remove_file_impl(const std::string &api_path) -> api_error {
curl::requests::http_delete del{}; curl::requests::http_delete del{};
del.allow_timeout = true; del.allow_timeout = true;
del.path = "/api/bus/object" + api_path; del.path = "/api/bus/objects" + api_path;
del.query["bucket"] = get_bucket(get_sia_config()); del.query["bucket"] = get_bucket(get_sia_config());
std::string error_data; std::string error_data;
@ -757,12 +697,12 @@ auto sia_provider::rename_file(const std::string &from_api_path,
try { try {
curl::requests::http_post post{}; curl::requests::http_post post{};
post.json = nlohmann::json({ post.json = nlohmann::json({
{"bucket", get_bucket(get_sia_config())},
{"from", from_api_path}, {"from", from_api_path},
{"to", to_api_path}, {"to", to_api_path},
{"mode", "single"}, {"mode", "single"},
}); });
post.path = "/api/bus/objects/rename"; post.path = "/api/bus/objects/rename";
post.query["bucket"] = get_bucket(get_sia_config());
std::string error_data; std::string error_data;
post.response_handler = [&error_data](auto &&data, long response_code) { post.response_handler = [&error_data](auto &&data, long response_code) {
@ -830,9 +770,8 @@ auto sia_provider::upload_file_impl(const std::string &api_path,
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
curl::requests::http_put_file put_file{}; curl::requests::http_put_file put_file{};
put_file.path = "/api/worker/object" + api_path; put_file.path = "/api/worker/objects" + api_path;
put_file.query["bucket"] = get_bucket(get_sia_config()); put_file.query["bucket"] = get_bucket(get_sia_config());
put_file.headers["content-type"] = "application/octet-stream";
put_file.source_path = source_path; put_file.source_path = source_path;
std::string error_data; std::string error_data;

View File

@ -38,58 +38,47 @@ void polling::frequency_thread(
std::function<std::uint32_t()> get_frequency_seconds, frequency freq) { std::function<std::uint32_t()> get_frequency_seconds, frequency freq) {
REPERTORY_USES_FUNCTION_NAME(); REPERTORY_USES_FUNCTION_NAME();
auto last_run = std::chrono::system_clock::time_point::min();
while (not get_stop_requested()) { while (not get_stop_requested()) {
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>( unique_mutex_lock lock(mutex_);
std::chrono::system_clock::now() - last_run); auto futures = std::accumulate(
auto max_elapsed = std::chrono::seconds(get_frequency_seconds()); items_.begin(), items_.end(), std::deque<tasks::task_ptr>{},
[this, &freq](auto &&list, auto &&item) -> auto {
if (last_run == std::chrono::system_clock::time_point::min() || if (item.second.freq != freq) {
elapsed >= max_elapsed) {
unique_mutex_lock lock(mutex_);
auto futures = std::accumulate(
items_.begin(), items_.end(), std::deque<tasks::task_ptr>{},
[this, &freq](auto &&list, auto &&item) -> auto {
if (item.second.freq != freq) {
return list;
}
auto future = tasks::instance().schedule({
[this, &freq, item](auto &&task_stopped) {
if (config_->get_event_level() == event_level::trace ||
freq != frequency::second) {
event_system::instance().raise<polling_item_begin>(
function_name, item.first);
}
item.second.action(task_stopped);
if (config_->get_event_level() == event_level::trace ||
freq != frequency::second) {
event_system::instance().raise<polling_item_end>(
function_name, item.first);
}
},
});
list.emplace_back(future);
return list; return list;
}
auto future = tasks::instance().schedule({
[this, &freq, item](auto &&task_stopped) {
if (config_->get_event_level() == event_level::trace ||
freq != frequency::second) {
event_system::instance().raise<polling_item_begin>(
function_name, item.first);
}
item.second.action(task_stopped);
if (config_->get_event_level() == event_level::trace ||
freq != frequency::second) {
event_system::instance().raise<polling_item_end>(
function_name, item.first);
}
},
}); });
lock.unlock();
while (not futures.empty()) { list.emplace_back(future);
futures.front()->wait(); return list;
futures.pop_front(); });
} lock.unlock();
last_run = std::chrono::system_clock::now(); while (not futures.empty()) {
elapsed = std::chrono::seconds(0U); futures.front()->wait();
futures.pop_front();
} }
unique_mutex_lock lock(mutex_);
if (get_stop_requested()) { if (get_stop_requested()) {
return; return;
} }
notify_.wait_for(lock, max_elapsed - elapsed); lock.lock();
notify_.wait_for(lock, std::chrono::seconds(get_frequency_seconds()));
} }
} }

View File

@ -23,38 +23,50 @@
#define REPERTORY_INCLUDE_CLI_CHECK_VERSION_HPP_ #define REPERTORY_INCLUDE_CLI_CHECK_VERSION_HPP_
#include "app_config.hpp" #include "app_config.hpp"
#include "comm/curl/curl_comm.hpp"
#include "providers/sia/sia_provider.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
namespace repertory::cli::actions { namespace repertory::cli::actions {
[[nodiscard]] inline auto check_version(std::vector<const char *> /* args */, [[nodiscard]] inline auto
const std::string &data_directory, check_version(std::vector<const char *> /* args */,
const provider_type &prov, const std::string & /* data_directory */,
const std::string & /*unique_id*/, const provider_type & /* pt */, const std::string & /*unique_id*/,
std::string /*user*/, std::string /*user*/, std::string /*password*/) -> exit_code {
std::string /*password*/) -> exit_code { auto ret = exit_code::success;
if (prov != provider_type::sia) {
fmt::println("Success:\n\tNo specific version is required for {} providers",
app_config::get_provider_display_name(prov));
return exit_code::success;
}
app_config config(prov, data_directory); // TODO need to updated way to check version
curl_comm comm(config.get_host_config()); // if (not((pt == provider_type::remote) || (pt == provider_type::s3))) {
sia_provider provider(config, comm); // app_config config(pt, data_directory);
// curl_comm comm(config);
// json data, err;
//
// if (comm.get("/daemon/version", data, err) == api_error::success) {
// const auto res = utils::compare_version_strings(
// data["version"].get<std::string>(),
// app_config::get_provider_minimum_version(pt));
// if (res < 0) {
// ret = exit_code::incompatible_version;
// std::cerr << "Failed!" << std::endl;
// std::cerr << " Actual: " << data["version"].get<std::string>()
// << std::endl;
// std::cerr << " Minimum: "
// << app_config::get_provider_minimum_version(pt) <<
// std::endl;
// } else {
// std::cout << "Success!" << std::endl;
// std::cout << " Actual: " << data["version"].get<std::string>()
// << std::endl;
// std::cout << " Minimum: "
// << app_config::get_provider_minimum_version(pt) <<
// std::endl;
// }
// } else {
// std::cerr << "Failed!" << std::endl;
// std::cerr << err.dump(2) << std::endl;
// ret = exit_code::communication_error;
// }
// }
std::string required_version; return ret;
std::string returned_version;
if (provider.check_version(required_version, returned_version)) {
fmt::println("Success:\n\tRequired: {}\n\tActual: {}", required_version,
returned_version);
return exit_code::success;
}
fmt::println("Failed:\n\tRequired: {}\n\tActual: {}", required_version,
returned_version);
return exit_code::incompatible_version;
} }
} // namespace repertory::cli::actions } // namespace repertory::cli::actions

View File

@ -27,7 +27,7 @@
namespace repertory::cli::actions { namespace repertory::cli::actions {
template <typename drive> inline void version(std::vector<const char *> args) { template <typename drive> inline void version(std::vector<const char *> args) {
std::cout << "Repertory core version: " << project_get_version() << std::endl; std::cout << "Repertory core version: " << project_get_version() << std::endl;
std::cout << "Repertory git revision: " << project_get_git_rev() << std::endl; std::cout << "Repertory Git revision: " << project_get_git_rev() << std::endl;
drive::display_version_information(args); drive::display_version_information(args);
} }
} // namespace repertory::cli::actions } // namespace repertory::cli::actions

View File

@ -41,7 +41,7 @@ using repertory_drive = repertory::winfsp_drive;
using remote_client = repertory::remote_winfsp::remote_client; using remote_client = repertory::remote_winfsp::remote_client;
using remote_drive = repertory::remote_winfsp::remote_winfsp_drive; using remote_drive = repertory::remote_winfsp::remote_winfsp_drive;
using remote_instance = repertory::remote_winfsp::i_remote_instance; using remote_instance = repertory::remote_winfsp::i_remote_instance;
#else // !defined(_WIN32) #else
#include "drives/fuse/fuse_drive.hpp" #include "drives/fuse/fuse_drive.hpp"
#include "drives/fuse/remotefuse/remote_client.hpp" #include "drives/fuse/remotefuse/remote_client.hpp"
#include "drives/fuse/remotefuse/remote_fuse_drive.hpp" #include "drives/fuse/remotefuse/remote_fuse_drive.hpp"
@ -50,7 +50,7 @@ using repertory_drive = repertory::fuse_drive;
using remote_client = repertory::remote_fuse::remote_client; using remote_client = repertory::remote_fuse::remote_client;
using remote_drive = repertory::remote_fuse::remote_fuse_drive; using remote_drive = repertory::remote_fuse::remote_fuse_drive;
using remote_instance = repertory::remote_fuse::i_remote_instance; using remote_instance = repertory::remote_fuse::i_remote_instance;
#endif // defined(_WIN32) #endif
namespace repertory::cli::actions { namespace repertory::cli::actions {
[[nodiscard]] inline auto [[nodiscard]] inline auto
@ -77,8 +77,7 @@ mount(std::vector<const char *> args, std::string data_directory,
config.set_remote_config(cfg); config.set_remote_config(cfg);
} else if (prov == provider_type::sia && } else if (prov == provider_type::sia &&
config.get_sia_config().bucket.empty()) { config.get_sia_config().bucket.empty()) {
[[maybe_unused]] auto bucket = config.set_value_by_name("SiaConfig.Bucket", unique_id);
config.set_value_by_name("SiaConfig.Bucket", unique_id);
} }
std::cout << "Generated " << app_config::get_provider_display_name(prov) std::cout << "Generated " << app_config::get_provider_display_name(prov)
@ -158,8 +157,7 @@ mount(std::vector<const char *> args, std::string data_directory,
} else { } else {
if (prov == provider_type::sia && if (prov == provider_type::sia &&
config.get_sia_config().bucket.empty()) { config.get_sia_config().bucket.empty()) {
[[maybe_unused]] auto bucket = config.set_value_by_name("SiaConfig.Bucket", unique_id);
config.set_value_by_name("SiaConfig.Bucket", unique_id);
} }
try { try {

View File

@ -268,8 +268,8 @@ public:
return file_path; return file_path;
} }
static auto create_file_and_test(std::string &file_name, mode_t perms) static auto create_file_and_test(std::string &file_name,
-> std::string { mode_t perms) -> std::string {
file_name += std::to_string(++provider_idx); file_name += std::to_string(++provider_idx);
auto file_path = utils::path::combine(mount_location, {file_name}); auto file_path = utils::path::combine(mount_location, {file_name});
@ -287,7 +287,7 @@ public:
EXPECT_TRUE(utils::file::file(file_path).exists()); EXPECT_TRUE(utils::file::file(file_path).exists());
EXPECT_FALSE(utils::file::directory(file_path).exists()); EXPECT_FALSE(utils::file::directory(file_path).exists());
struct stat64 unix_st{}; struct stat64 unix_st {};
EXPECT_EQ(0, stat64(file_path.c_str(), &unix_st)); EXPECT_EQ(0, stat64(file_path.c_str(), &unix_st));
EXPECT_EQ(getgid(), unix_st.st_gid); EXPECT_EQ(getgid(), unix_st.st_gid);
EXPECT_EQ(getuid(), unix_st.st_uid); EXPECT_EQ(getuid(), unix_st.st_uid);
@ -299,8 +299,8 @@ public:
return create_file_and_test(file_name, ACCESSPERMS); return create_file_and_test(file_name, ACCESSPERMS);
} }
static auto create_directory_and_test(std::string &dir_name, mode_t perms) static auto create_directory_and_test(std::string &dir_name,
-> std::string { mode_t perms) -> std::string {
dir_name += std::to_string(++provider_idx); dir_name += std::to_string(++provider_idx);
auto dir_path = utils::path::combine(mount_location, {dir_name}); auto dir_path = utils::path::combine(mount_location, {dir_name});
@ -309,7 +309,7 @@ public:
EXPECT_TRUE(utils::file::directory(dir_path).exists()); EXPECT_TRUE(utils::file::directory(dir_path).exists());
EXPECT_FALSE(utils::file::file(dir_path).exists()); EXPECT_FALSE(utils::file::file(dir_path).exists());
struct stat64 unix_st{}; struct stat64 unix_st {};
EXPECT_EQ(0, stat64(dir_path.c_str(), &unix_st)); EXPECT_EQ(0, stat64(dir_path.c_str(), &unix_st));
EXPECT_EQ(getgid(), unix_st.st_gid); EXPECT_EQ(getgid(), unix_st.st_gid);
EXPECT_EQ(getuid(), unix_st.st_uid); EXPECT_EQ(getuid(), unix_st.st_uid);
@ -410,9 +410,9 @@ std::string fuse_test<provider_t>::mount_location;
template <typename provider_t> template <typename provider_t>
std::string fuse_test<provider_t>::mount_location2; std::string fuse_test<provider_t>::mount_location2;
// using fuse_provider_types = ::testing::Types<local_s3, remote_s3>; using fuse_provider_types = ::testing::Types<local_s3, remote_s3>;
using fuse_provider_types = // using fuse_provider_types =
::testing::Types<local_s3, remote_s3, local_sia, remote_sia>; // ::testing::Types<local_s3, remote_s3, local_sia, remote_sia>;
} // namespace repertory } // namespace repertory
#endif // !defined(_WIN32) #endif // !defined(_WIN32)

View File

@ -36,10 +36,6 @@ private:
const bool allow_rename_; const bool allow_rename_;
public: public:
MOCK_METHOD(bool, check_version,
(std::string & required_version, std::string &returned_version),
(const, override));
MOCK_METHOD(api_error, create_directory, MOCK_METHOD(api_error, create_directory,
(const std::string &api_path, api_meta_map &meta), (override)); (const std::string &api_path, api_meta_map &meta), (override));

View File

@ -1,763 +0,0 @@
/*
Copyright <2018-2025> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "test_common.hpp"
#include "app_config.hpp"
#include "utils/path.hpp"
namespace repertory {
class app_config_test : public ::testing::Test {
public:
static std::atomic<std::uint64_t> idx;
std::string encrypt_directory;
std::string remote_directory;
std::string s3_directory;
std::string sia_directory;
void SetUp() override {
encrypt_directory = utils::path::combine(test::get_test_output_dir(),
{
"app_config_test",
"encrypt",
std::to_string(++idx),
});
remote_directory = utils::path::combine(test::get_test_output_dir(),
{
"app_config_test",
"remote",
std::to_string(++idx),
});
s3_directory = utils::path::combine(test::get_test_output_dir(),
{
"app_config_test",
"s3",
std::to_string(++idx),
});
sia_directory = utils::path::combine(test::get_test_output_dir(),
{
"app_config_test",
"sia",
std::to_string(++idx),
});
}
};
static void remove_unused_types(auto &data, provider_type prov) {
switch (prov) {
case provider_type::encrypt:
data.erase(JSON_DOWNLOAD_TIMEOUT_SECS);
data.erase(JSON_ENABLE_DOWNLOAD_TIMEOUT);
data.erase(JSON_EVICTION_DELAY_MINS);
data.erase(JSON_EVICTION_USE_ACCESS_TIME);
data.erase(JSON_HOST_CONFIG);
data.erase(JSON_MAX_CACHE_SIZE_BYTES);
data.erase(JSON_MAX_UPLOAD_COUNT);
data.erase(JSON_ONLINE_CHECK_RETRY_SECS);
data.erase(JSON_PREFERRED_DOWNLOAD_TYPE);
data.erase(JSON_REMOTE_CONFIG);
data.erase(JSON_RETRY_READ_COUNT);
data.erase(JSON_RING_BUFFER_FILE_SIZE);
data.erase(JSON_S3_CONFIG);
data.erase(JSON_SIA_CONFIG);
break;
case provider_type::remote:
data.erase(JSON_DATABASE_TYPE);
data.erase(JSON_DOWNLOAD_TIMEOUT_SECS);
data.erase(JSON_ENABLE_DOWNLOAD_TIMEOUT);
data.erase(JSON_ENCRYPT_CONFIG);
data.erase(JSON_EVICTION_DELAY_MINS);
data.erase(JSON_EVICTION_USE_ACCESS_TIME);
data.erase(JSON_HIGH_FREQ_INTERVAL_SECS);
data.erase(JSON_HOST_CONFIG);
data.erase(JSON_LOW_FREQ_INTERVAL_SECS);
data.erase(JSON_MAX_CACHE_SIZE_BYTES);
data.erase(JSON_MAX_UPLOAD_COUNT);
data.erase(JSON_MED_FREQ_INTERVAL_SECS);
data.erase(JSON_ONLINE_CHECK_RETRY_SECS);
data.erase(JSON_PREFERRED_DOWNLOAD_TYPE);
data.erase(JSON_REMOTE_MOUNT);
data.erase(JSON_RETRY_READ_COUNT);
data.erase(JSON_RING_BUFFER_FILE_SIZE);
data.erase(JSON_S3_CONFIG);
data.erase(JSON_SIA_CONFIG);
break;
case provider_type::s3:
data.erase(JSON_ENCRYPT_CONFIG);
data.erase(JSON_HOST_CONFIG);
data.erase(JSON_REMOTE_CONFIG);
data.erase(JSON_SIA_CONFIG);
break;
case provider_type::sia:
data.erase(JSON_ENCRYPT_CONFIG);
data.erase(JSON_REMOTE_CONFIG);
data.erase(JSON_S3_CONFIG);
break;
default:
return;
}
}
std::atomic<std::uint64_t> app_config_test::idx{0U};
static void defaults_tests(const json &json_data, provider_type prov) {
json json_defaults = {
{JSON_API_PORT, app_config::default_rpc_port(prov)},
{JSON_API_USER, std::string{REPERTORY}},
{JSON_DOWNLOAD_TIMEOUT_SECS, default_download_timeout_secs},
{JSON_DATABASE_TYPE, database_type::rocksdb},
{JSON_ENABLE_DOWNLOAD_TIMEOUT, true},
{JSON_ENABLE_DRIVE_EVENTS, false},
#if defined(_WIN32)
{JSON_ENABLE_MOUNT_MANAGER, false},
#endif // defined(_WIN32)
{JSON_ENCRYPT_CONFIG, encrypt_config{}},
{JSON_EVENT_LEVEL, event_level::info},
{JSON_EVICTION_DELAY_MINS, default_eviction_delay_mins},
{JSON_EVICTION_USE_ACCESS_TIME, false},
{JSON_HIGH_FREQ_INTERVAL_SECS, default_high_freq_interval_secs},
{JSON_HOST_CONFIG, host_config{}},
{JSON_LOW_FREQ_INTERVAL_SECS, default_low_freq_interval_secs},
{JSON_MAX_CACHE_SIZE_BYTES, default_max_cache_size_bytes},
{JSON_MAX_UPLOAD_COUNT, default_max_upload_count},
{JSON_MED_FREQ_INTERVAL_SECS, default_med_freq_interval_secs},
{JSON_ONLINE_CHECK_RETRY_SECS, default_online_check_retry_secs},
{JSON_PREFERRED_DOWNLOAD_TYPE, download_type::default_},
{JSON_REMOTE_CONFIG, remote::remote_config{}},
{JSON_REMOTE_MOUNT, remote::remote_mount{}},
{JSON_RETRY_READ_COUNT, default_retry_read_count},
{JSON_RING_BUFFER_FILE_SIZE, default_ring_buffer_file_size},
{JSON_S3_CONFIG, s3_config{}},
{JSON_SIA_CONFIG, sia_config{}},
{JSON_TASK_WAIT_MS, default_task_wait_ms},
{JSON_VERSION, REPERTORY_CONFIG_VERSION},
};
remove_unused_types(json_defaults, prov);
switch (prov) {
case provider_type::encrypt:
json_defaults[JSON_REMOTE_MOUNT][JSON_API_PORT] =
app_config::default_remote_api_port(prov);
break;
json_defaults[JSON_REMOTE_MOUNT][JSON_API_PORT] =
app_config::default_remote_api_port(prov);
break;
case provider_type::sia:
json_defaults[JSON_HOST_CONFIG][JSON_API_PORT] =
app_config::default_api_port(prov);
json_defaults[JSON_HOST_CONFIG][JSON_AGENT_STRING] =
app_config::default_agent_name(prov);
json_defaults[JSON_REMOTE_MOUNT][JSON_API_PORT] =
app_config::default_remote_api_port(prov);
break;
default:
return;
}
fmt::println("testing default|{}-{}", app_config::get_provider_name(prov),
JSON_API_AUTH);
ASSERT_EQ(std::size_t(default_api_auth_size),
json_data.at(JSON_API_AUTH).get<std::string>().size());
for (const auto &[key, value] : json_defaults.items()) {
fmt::println("testing default|{}-{}", app_config::get_provider_name(prov),
key);
EXPECT_EQ(value, json_data.at(key));
}
}
template <typename get_t, typename set_t, typename val_t>
static void test_getter_setter(app_config &cfg, get_t getter, set_t setter,
val_t val1, val_t val2, const std::string &key,
const std::string &val_str) {
(cfg.*setter)(val1);
ASSERT_TRUE((cfg.*getter)() == val1);
(cfg.*setter)(val2);
ASSERT_TRUE((cfg.*getter)() == val2);
if (key.empty()) {
return;
}
EXPECT_STREQ(val_str.c_str(), cfg.set_value_by_name(key, val_str).c_str());
}
static void common_tests(app_config &config, provider_type prov) {
ASSERT_EQ(config.get_provider_type(), prov);
std::map<std::string_view, std::function<void(app_config &)>> methods{
{JSON_API_AUTH,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_api_auth,
&app_config::set_api_auth, "", "auth",
JSON_API_AUTH, "auth2");
}},
{JSON_API_PORT,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_api_port,
&app_config::set_api_port, std::uint16_t{0U},
std::uint16_t{1024U}, JSON_API_PORT, "1025");
}},
{JSON_API_USER,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_api_user,
&app_config::set_api_user, "", "user",
JSON_API_USER, "user2");
}},
{JSON_DOWNLOAD_TIMEOUT_SECS,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_download_timeout_secs,
&app_config::set_download_timeout_secs,
std::uint8_t{min_download_timeout_secs + 1U},
std::uint8_t{min_download_timeout_secs + 2U},
JSON_DOWNLOAD_TIMEOUT_SECS,
std::to_string(min_download_timeout_secs + 2U));
cfg.set_download_timeout_secs(min_download_timeout_secs - 1U);
EXPECT_EQ(min_download_timeout_secs, cfg.get_download_timeout_secs());
}},
{JSON_DATABASE_TYPE,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_database_type,
&app_config::set_database_type,
database_type::rocksdb, database_type::sqlite,
JSON_DATABASE_TYPE, "rocksdb");
}},
{JSON_ENABLE_DOWNLOAD_TIMEOUT,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_enable_download_timeout,
&app_config::set_enable_download_timeout, true,
false, JSON_ENABLE_DOWNLOAD_TIMEOUT, "1");
}},
{JSON_ENABLE_DRIVE_EVENTS,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_enable_drive_events,
&app_config::set_enable_drive_events, true, false,
JSON_ENABLE_DRIVE_EVENTS, "1");
}},
#if defined(_WIN32)
{JSON_ENABLE_MOUNT_MANAGER,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_enable_mount_manager,
&app_config::set_enable_mount_manager, true, false,
JSON_ENABLE_MOUNT_MANAGER, "1");
}},
#endif // defined(_WIN32)
{JSON_ENCRYPT_CONFIG,
[](app_config &cfg) {
encrypt_config cfg1{};
cfg1.encryption_token = "1";
cfg1.path = "2";
encrypt_config cfg2{};
cfg2.encryption_token = "2";
cfg2.path = "1";
ASSERT_NE(cfg1, cfg2);
test_getter_setter(cfg, &app_config::get_encrypt_config,
&app_config::set_encrypt_config, cfg1, cfg2, "",
"");
encrypt_config cfg3{};
cfg3.encryption_token = "3";
cfg3.path = "4";
auto value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_ENCRYPT_CONFIG, JSON_ENCRYPTION_TOKEN),
cfg3.encryption_token);
EXPECT_STREQ(cfg3.encryption_token.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_ENCRYPT_CONFIG, JSON_PATH), cfg3.path);
EXPECT_STREQ(cfg3.path.c_str(), value.c_str());
}},
{JSON_EVENT_LEVEL,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_event_level,
&app_config::set_event_level, event_level::critical,
event_level::debug, JSON_EVENT_LEVEL, "info");
}},
{JSON_EVICTION_DELAY_MINS,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_eviction_delay_mins,
&app_config::set_eviction_delay_mins,
std::uint32_t{0U}, std::uint32_t{1U},
JSON_EVICTION_DELAY_MINS, "2");
}},
{JSON_EVICTION_USE_ACCESS_TIME,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_eviction_uses_accessed_time,
&app_config::set_eviction_uses_accessed_time, true,
false, JSON_EVICTION_USE_ACCESS_TIME, "1");
}},
{JSON_HIGH_FREQ_INTERVAL_SECS,
[](app_config &cfg) {
test_getter_setter(
cfg, &app_config::get_high_frequency_interval_secs,
&app_config::set_high_frequency_interval_secs,
std::uint16_t{default_high_freq_interval_secs + 1U},
std::uint16_t{default_high_freq_interval_secs + 2U},
JSON_HIGH_FREQ_INTERVAL_SECS,
std::to_string(default_high_freq_interval_secs + 3U));
cfg.set_high_frequency_interval_secs(0U);
EXPECT_EQ(1U, cfg.get_high_frequency_interval_secs());
}},
{JSON_HOST_CONFIG,
[](app_config &cfg) {
host_config cfg1{};
cfg1.agent_string = "1";
cfg1.api_password = "2";
cfg1.api_user = "3";
cfg1.api_port = 4U;
cfg1.host_name_or_ip = "5";
cfg1.path = "6";
cfg1.protocol = "http";
cfg1.timeout_ms = 8U;
host_config cfg2{};
cfg2.agent_string = "9";
cfg2.api_password = "10";
cfg2.api_user = "11";
cfg2.api_port = 12U;
cfg2.host_name_or_ip = "13";
cfg2.path = "14";
cfg2.protocol = "https";
cfg2.timeout_ms = 16U;
ASSERT_NE(cfg1, cfg2);
test_getter_setter(cfg, &app_config::get_host_config,
&app_config::set_host_config, cfg1, cfg2, "", "");
host_config cfg3{};
cfg3.agent_string = "17";
cfg3.api_password = "18";
cfg3.api_user = "19";
cfg3.api_port = 20U;
cfg3.host_name_or_ip = "21";
cfg3.path = "22";
cfg3.protocol = "http";
cfg3.timeout_ms = 24;
auto value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_AGENT_STRING),
cfg3.agent_string);
EXPECT_STREQ(cfg3.agent_string.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_API_PASSWORD),
cfg3.api_password);
EXPECT_STREQ(cfg3.api_password.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_API_USER),
cfg3.api_user);
EXPECT_STREQ(cfg3.api_user.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_API_PORT),
std::to_string(cfg3.api_port));
EXPECT_STREQ(std::to_string(cfg3.api_port).c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_HOST_NAME_OR_IP),
cfg3.host_name_or_ip);
EXPECT_STREQ(cfg3.host_name_or_ip.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_PATH), cfg3.path);
EXPECT_STREQ(cfg3.path.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_PROTOCOL),
cfg3.protocol);
EXPECT_STREQ(cfg3.protocol.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_HOST_CONFIG, JSON_TIMEOUT_MS),
std::to_string(cfg3.timeout_ms));
EXPECT_STREQ(std::to_string(cfg3.timeout_ms).c_str(), value.c_str());
}},
{JSON_LOW_FREQ_INTERVAL_SECS,
[](app_config &cfg) {
test_getter_setter(
cfg, &app_config::get_low_frequency_interval_secs,
&app_config::set_low_frequency_interval_secs,
std::uint16_t{default_low_freq_interval_secs + 1U},
std::uint16_t{default_low_freq_interval_secs + 2U},
JSON_LOW_FREQ_INTERVAL_SECS,
std::to_string(default_low_freq_interval_secs + 3U));
cfg.set_low_frequency_interval_secs(0U);
EXPECT_EQ(1U, cfg.get_low_frequency_interval_secs());
}},
{JSON_MAX_CACHE_SIZE_BYTES,
[](app_config &cfg) {
test_getter_setter(
cfg, &app_config::get_max_cache_size_bytes,
&app_config::set_max_cache_size_bytes, min_cache_size_bytes + 1U,
min_cache_size_bytes + 2U, JSON_MAX_CACHE_SIZE_BYTES,
std::to_string(min_cache_size_bytes + 3U));
cfg.set_max_cache_size_bytes(min_cache_size_bytes - 1U);
EXPECT_EQ(min_cache_size_bytes, cfg.get_max_cache_size_bytes());
}},
{JSON_MAX_UPLOAD_COUNT,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_max_upload_count,
&app_config::set_max_upload_count, std::uint8_t{1U},
std::uint8_t{2U}, JSON_MAX_UPLOAD_COUNT, "3");
cfg.set_max_upload_count(0U);
EXPECT_EQ(1U, cfg.get_max_upload_count());
}},
{JSON_MED_FREQ_INTERVAL_SECS,
[](app_config &cfg) {
test_getter_setter(
cfg, &app_config::get_med_frequency_interval_secs,
&app_config::set_med_frequency_interval_secs,
std::uint16_t{default_med_freq_interval_secs + 1U},
std::uint16_t{default_med_freq_interval_secs + 2U},
JSON_MED_FREQ_INTERVAL_SECS,
std::to_string(default_med_freq_interval_secs + 3U));
cfg.set_med_frequency_interval_secs(0U);
EXPECT_EQ(1U, cfg.get_med_frequency_interval_secs());
}},
{JSON_ONLINE_CHECK_RETRY_SECS,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_online_check_retry_secs,
&app_config::set_online_check_retry_secs,
std::uint16_t{min_online_check_retry_secs + 1U},
std::uint16_t{min_online_check_retry_secs + 2U},
JSON_ONLINE_CHECK_RETRY_SECS,
std::to_string(min_online_check_retry_secs + 3U));
cfg.set_online_check_retry_secs(min_online_check_retry_secs - 1U);
EXPECT_EQ(min_online_check_retry_secs,
cfg.get_online_check_retry_secs());
}},
{JSON_PREFERRED_DOWNLOAD_TYPE,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_preferred_download_type,
&app_config::set_preferred_download_type,
download_type::direct, download_type::default_,
JSON_PREFERRED_DOWNLOAD_TYPE, "ring_buffer");
}},
{JSON_REMOTE_CONFIG,
[](app_config &cfg) {
remote::remote_config remote_cfg1{};
remote_cfg1.api_port = 1U;
remote_cfg1.encryption_token = "2";
remote_cfg1.host_name_or_ip = "3";
remote_cfg1.max_connections = 4U;
remote_cfg1.recv_timeout_ms = 5U;
remote_cfg1.send_timeout_ms = 6U;
remote::remote_config remote_cfg2{};
remote_cfg1.api_port = 6U;
remote_cfg1.encryption_token = "5";
remote_cfg1.host_name_or_ip = "4";
remote_cfg1.max_connections = 3U;
remote_cfg1.recv_timeout_ms = 2U;
remote_cfg1.send_timeout_ms = 1U;
ASSERT_NE(remote_cfg1, remote_cfg2);
test_getter_setter(cfg, &app_config::get_remote_config,
&app_config::set_remote_config, remote_cfg1,
remote_cfg2, "", "");
remote::remote_config remote_cfg3{};
remote_cfg1.api_port = 7U;
remote_cfg1.encryption_token = "8";
remote_cfg1.host_name_or_ip = "9";
remote_cfg1.max_connections = 10U;
remote_cfg1.recv_timeout_ms = 11U;
remote_cfg1.send_timeout_ms = 12U;
auto value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_CONFIG, JSON_API_PORT),
std::to_string(remote_cfg3.api_port));
EXPECT_STREQ(std::to_string(remote_cfg3.api_port).c_str(),
value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_CONFIG, JSON_ENCRYPTION_TOKEN),
remote_cfg3.encryption_token);
EXPECT_STREQ(remote_cfg3.encryption_token.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_CONFIG, JSON_HOST_NAME_OR_IP),
remote_cfg3.host_name_or_ip);
EXPECT_STREQ(remote_cfg3.host_name_or_ip.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_CONFIG, JSON_MAX_CONNECTIONS),
std::to_string(remote_cfg3.max_connections));
EXPECT_STREQ(std::to_string(remote_cfg3.max_connections).c_str(),
value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_CONFIG, JSON_RECV_TIMEOUT_MS),
std::to_string(remote_cfg3.recv_timeout_ms));
EXPECT_STREQ(std::to_string(remote_cfg3.recv_timeout_ms).c_str(),
value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_CONFIG, JSON_SEND_TIMEOUT_MS),
std::to_string(remote_cfg3.send_timeout_ms));
EXPECT_STREQ(std::to_string(remote_cfg3.send_timeout_ms).c_str(),
value.c_str());
}},
{JSON_REMOTE_MOUNT,
[](app_config &cfg) {
remote::remote_mount mnt_cfg1{};
mnt_cfg1.api_port = 1U;
mnt_cfg1.client_pool_size = 2U;
mnt_cfg1.enable = false;
mnt_cfg1.encryption_token = "3";
remote::remote_mount mnt_cfg2{};
mnt_cfg2.api_port = 3U;
mnt_cfg2.client_pool_size = 4U;
mnt_cfg2.enable = true;
mnt_cfg2.encryption_token = "5";
ASSERT_NE(mnt_cfg1, mnt_cfg2);
test_getter_setter(cfg, &app_config::get_remote_mount,
&app_config::set_remote_mount, mnt_cfg1, mnt_cfg2,
"", "");
remote::remote_mount mnt_cfg3{};
mnt_cfg3.api_port = 9U;
mnt_cfg3.client_pool_size = 10U;
mnt_cfg3.enable = false;
mnt_cfg3.encryption_token = "11";
auto value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_MOUNT, JSON_API_PORT),
std::to_string(mnt_cfg3.api_port));
EXPECT_STREQ(std::to_string(mnt_cfg3.api_port).c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_MOUNT, JSON_CLIENT_POOL_SIZE),
std::to_string(mnt_cfg3.client_pool_size));
EXPECT_STREQ(std::to_string(mnt_cfg3.client_pool_size).c_str(),
value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_REMOTE_MOUNT, JSON_ENABLE_REMOTE_MOUNT),
utils::string::from_bool(mnt_cfg3.enable));
EXPECT_STREQ(utils::string::from_bool(mnt_cfg3.enable).c_str(),
value.c_str());
}},
{JSON_RETRY_READ_COUNT,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_retry_read_count,
&app_config::set_retry_read_count,
std::uint16_t{min_retry_read_count + 1U},
std::uint16_t{min_retry_read_count + 2U},
JSON_RETRY_READ_COUNT,
std::to_string(min_retry_read_count + 3U));
cfg.set_retry_read_count(min_retry_read_count - 1U);
EXPECT_EQ(min_retry_read_count, cfg.get_retry_read_count());
}},
{JSON_RING_BUFFER_FILE_SIZE,
[](app_config &cfg) {
test_getter_setter(cfg, &app_config::get_ring_buffer_file_size,
&app_config::set_ring_buffer_file_size,
std::uint16_t{min_ring_buffer_file_size + 1U},
std::uint16_t{min_ring_buffer_file_size + 2U},
JSON_RING_BUFFER_FILE_SIZE,
std::to_string(min_ring_buffer_file_size + 3U));
cfg.set_ring_buffer_file_size(min_ring_buffer_file_size - 1U);
EXPECT_EQ(min_ring_buffer_file_size, cfg.get_ring_buffer_file_size());
cfg.set_ring_buffer_file_size(max_ring_buffer_file_size + 1U);
EXPECT_EQ(max_ring_buffer_file_size, cfg.get_ring_buffer_file_size());
}},
{JSON_S3_CONFIG,
[](auto &&cfg) {
s3_config cfg1{};
cfg1.access_key = "1";
cfg1.bucket = "2";
cfg1.encryption_token = "3";
cfg1.region = "4";
cfg1.secret_key = "5";
cfg1.timeout_ms = 6U;
cfg1.url = "7";
cfg1.use_path_style = false;
cfg1.use_region_in_url = false;
s3_config cfg2{};
cfg2.access_key = "8";
cfg2.bucket = "9";
cfg2.encryption_token = "10";
cfg2.region = "11";
cfg2.secret_key = "12";
cfg2.timeout_ms = 13U;
cfg2.url = "14";
cfg2.use_path_style = true;
cfg2.use_region_in_url = true;
ASSERT_NE(cfg1, cfg2);
test_getter_setter(cfg, &app_config::get_s3_config,
&app_config::set_s3_config, cfg1, cfg2, "", "");
s3_config cfg3{};
cfg3.access_key = "8";
cfg3.bucket = "9";
cfg3.encryption_token = "10";
cfg3.region = "11";
cfg3.secret_key = "12";
cfg3.timeout_ms = 13U;
cfg3.url = "14";
cfg3.use_path_style = true;
cfg3.use_region_in_url = true;
auto value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_ACCESS_KEY),
cfg3.access_key);
EXPECT_STREQ(cfg3.access_key.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_BUCKET), cfg3.bucket);
EXPECT_STREQ(cfg3.bucket.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_ENCRYPTION_TOKEN),
cfg3.encryption_token);
EXPECT_STREQ(cfg3.encryption_token.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_REGION), cfg3.region);
EXPECT_STREQ(cfg3.region.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_SECRET_KEY),
cfg3.secret_key);
EXPECT_STREQ(cfg3.secret_key.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_TIMEOUT_MS),
std::to_string(cfg3.timeout_ms));
EXPECT_STREQ(std::to_string(cfg3.timeout_ms).c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_URL), cfg3.url);
EXPECT_STREQ(cfg3.url.c_str(), value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_USE_PATH_STYLE),
utils::string::from_bool(cfg3.use_path_style));
EXPECT_STREQ(utils::string::from_bool(cfg3.use_path_style).c_str(),
value.c_str());
value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_S3_CONFIG, JSON_USE_REGION_IN_URL),
utils::string::from_bool(cfg3.use_region_in_url));
EXPECT_STREQ(utils::string::from_bool(cfg3.use_region_in_url).c_str(),
value.c_str());
}},
{JSON_SIA_CONFIG,
[](app_config &cfg) {
sia_config cfg1{};
cfg1.bucket = "1";
sia_config cfg2{};
cfg2.bucket = "2";
ASSERT_NE(cfg1, cfg2);
test_getter_setter(cfg, &app_config::get_sia_config,
&app_config::set_sia_config, cfg1, cfg2, "", "");
sia_config cfg3{};
cfg3.bucket = "3";
auto value = cfg.set_value_by_name(
fmt::format("{}.{}", JSON_SIA_CONFIG, JSON_BUCKET), cfg3.bucket);
EXPECT_STREQ(cfg3.bucket.c_str(), value.c_str());
}},
{JSON_TASK_WAIT_MS,
[](app_config &cfg) {
test_getter_setter(
cfg, &app_config::get_task_wait_ms, &app_config::set_task_wait_ms,
std::uint16_t{min_task_wait_ms + 1U},
std::uint16_t{min_task_wait_ms + 2U}, JSON_TASK_WAIT_MS,
std::to_string(min_task_wait_ms + 3U));
cfg.set_task_wait_ms(min_task_wait_ms - 1U);
EXPECT_EQ(min_task_wait_ms, cfg.get_task_wait_ms());
}},
};
remove_unused_types(methods, prov);
for (const auto &[key, test_function] : methods) {
fmt::println("testing setting|{}-{}", app_config::get_provider_name(prov),
key);
test_function(config);
}
}
TEST_F(app_config_test, encrypt_config) {
app_config config(provider_type::encrypt, encrypt_directory);
defaults_tests(config.get_json(), provider_type::encrypt);
common_tests(config, provider_type::encrypt);
}
TEST_F(app_config_test, remote_config) {
app_config config(provider_type::remote, remote_directory);
defaults_tests(config.get_json(), provider_type::remote);
common_tests(config, provider_type::remote);
}
TEST_F(app_config_test, s3_config) {
app_config config(provider_type::s3, s3_directory);
defaults_tests(config.get_json(), provider_type::s3);
common_tests(config, provider_type::s3);
}
TEST_F(app_config_test, sia_config) {
app_config config(provider_type::sia, sia_directory);
defaults_tests(config.get_json(), provider_type::sia);
common_tests(config, provider_type::sia);
}
} // namespace repertory

View File

@ -24,7 +24,7 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
namespace repertory { namespace repertory {
TEST(atomic_test, atomic_primitive) { TEST(atomic, atomic_primitive) {
atomic<std::uint16_t> value; atomic<std::uint16_t> value;
value = 5U; value = 5U;
EXPECT_EQ(5U, static_cast<std::uint16_t>(value)); EXPECT_EQ(5U, static_cast<std::uint16_t>(value));
@ -35,7 +35,7 @@ TEST(atomic_test, atomic_primitive) {
EXPECT_EQ(6U, value.load()); EXPECT_EQ(6U, value.load());
} }
TEST(atomic_test, atomic_primitive_equality) { TEST(atomic, atomic_primitive_equality) {
atomic<std::uint16_t> value1{5U}; atomic<std::uint16_t> value1{5U};
atomic<std::uint16_t> value2{5U}; atomic<std::uint16_t> value2{5U};
EXPECT_EQ(value1, value1); EXPECT_EQ(value1, value1);
@ -45,7 +45,7 @@ TEST(atomic_test, atomic_primitive_equality) {
EXPECT_EQ(static_cast<std::uint16_t>(value2), 5U); EXPECT_EQ(static_cast<std::uint16_t>(value2), 5U);
} }
TEST(atomic_test, atomic_primitive_inequality) { TEST(atomic, atomic_primitive_inequality) {
atomic<std::uint16_t> value1{5U}; atomic<std::uint16_t> value1{5U};
atomic<std::uint16_t> value2{6U}; atomic<std::uint16_t> value2{6U};
EXPECT_NE(value1, value2); EXPECT_NE(value1, value2);
@ -53,7 +53,7 @@ TEST(atomic_test, atomic_primitive_inequality) {
EXPECT_NE(static_cast<std::uint16_t>(value2), 5U); EXPECT_NE(static_cast<std::uint16_t>(value2), 5U);
} }
TEST(atomic_test, atomic_struct) { TEST(atomic, atomic_struct) {
atomic<encrypt_config> value{ atomic<encrypt_config> value{
encrypt_config{ encrypt_config{
.encryption_token = "token", .encryption_token = "token",

View File

@ -0,0 +1,696 @@
/*
Copyright <2018-2025> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "test_common.hpp"
#include "app_config.hpp"
#include "events/event_system.hpp"
#include "utils/common.hpp"
#include "utils/file_utils.hpp"
#include "utils/path.hpp"
namespace repertory {
class config_test : public ::testing::Test {
public:
console_consumer cs;
static std::atomic<std::uint64_t> idx;
std::string s3_directory;
std::string sia_directory;
void SetUp() override {
s3_directory = utils::path::combine(test::get_test_output_dir(),
{
"config_test",
"s3",
std::to_string(++idx),
});
sia_directory = utils::path::combine(test::get_test_output_dir(),
{
"config_test",
"sia",
std::to_string(++idx),
});
event_system::instance().start();
}
void TearDown() override {
event_system::instance().stop();
}
};
std::atomic<std::uint64_t> config_test::idx{0U};
TEST_F(config_test, api_path) {
std::string original_value;
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_api_auth();
EXPECT_EQ(48U, original_value.size());
}
}
TEST_F(config_test, api_auth) {
std::string original_value;
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_api_auth();
config.set_api_auth(original_value.substr(0, 20));
EXPECT_EQ(original_value.substr(0, 20), config.get_api_auth());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value.substr(0, 20), config.get_api_auth());
}
}
TEST_F(config_test, api_port) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_api_port();
config.set_api_port(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_api_port());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_api_port());
}
}
TEST_F(config_test, api_user) {
std::string original_value;
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_api_user();
config.set_api_user(original_value.substr(0, 2));
EXPECT_EQ(original_value.substr(0, 2), config.get_api_user());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value.substr(0, 2), config.get_api_user());
}
}
TEST_F(config_test, download_timeout_secs) {
std::uint8_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_download_timeout_secs();
config.set_download_timeout_secs(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_download_timeout_secs());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_download_timeout_secs());
}
}
TEST_F(config_test, enable_download_timeout) {
bool original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_enable_download_timeout();
config.set_enable_download_timeout(not original_value);
EXPECT_EQ(not original_value, config.get_enable_download_timeout());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(not original_value, config.get_enable_download_timeout());
}
}
TEST_F(config_test, enable_drive_events) {
bool original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_enable_drive_events();
config.set_enable_drive_events(not original_value);
EXPECT_EQ(not original_value, config.get_enable_drive_events());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(not original_value, config.get_enable_drive_events());
}
}
#if defined(_WIN32)
TEST_F(config_test, enable_mount_manager) {
bool original_value;
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_enable_mount_manager();
config.set_enable_mount_manager(not original_value);
EXPECT_EQ(not original_value, config.get_enable_mount_manager());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(not original_value, config.get_enable_mount_manager());
}
}
#endif
TEST_F(config_test, event_level) {
{
app_config config(provider_type::sia, sia_directory);
config.set_event_level(event_level::debug);
EXPECT_EQ(event_level::debug, config.get_event_level());
config.set_event_level(event_level::warn);
EXPECT_EQ(event_level::warn, config.get_event_level());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(event_level::warn, config.get_event_level());
}
}
TEST_F(config_test, eviction_delay_mins) {
std::uint32_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_eviction_delay_mins();
config.set_eviction_delay_mins(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_eviction_delay_mins());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_eviction_delay_mins());
}
}
TEST_F(config_test, eviction_uses_accessed_time) {
bool original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_eviction_uses_accessed_time();
config.set_eviction_uses_accessed_time(not original_value);
EXPECT_EQ(not original_value, config.get_eviction_uses_accessed_time());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(not original_value, config.get_eviction_uses_accessed_time());
}
}
TEST_F(config_test, high_frequency_interval_secs) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_high_frequency_interval_secs();
config.set_high_frequency_interval_secs(original_value + 5U);
EXPECT_EQ(original_value + 5U, config.get_high_frequency_interval_secs());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5U, config.get_high_frequency_interval_secs());
}
}
TEST_F(config_test, low_frequency_interval_secs) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_low_frequency_interval_secs();
config.set_low_frequency_interval_secs(original_value + 5U);
EXPECT_EQ(original_value + 5U, config.get_low_frequency_interval_secs());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5U, config.get_low_frequency_interval_secs());
}
}
TEST_F(config_test, med_frequency_interval_secs) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_med_frequency_interval_secs();
config.set_med_frequency_interval_secs(original_value + 5U);
EXPECT_EQ(original_value + 5U, config.get_med_frequency_interval_secs());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5U, config.get_med_frequency_interval_secs());
}
}
TEST_F(config_test, max_cache_size_bytes) {
{
app_config config(provider_type::sia, sia_directory);
config.set_max_cache_size_bytes(100 * 1024 * 1024);
EXPECT_EQ(100U * 1024 * 1024, config.get_max_cache_size_bytes());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(100U * 1024 * 1024, config.get_max_cache_size_bytes());
}
}
TEST_F(config_test, max_upload_count) {
{
app_config config(provider_type::sia, sia_directory);
config.set_max_upload_count(8U);
EXPECT_EQ(std::uint8_t(8U), config.get_max_upload_count());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(std::uint8_t(8U), config.get_max_upload_count());
}
{
app_config config(provider_type::sia, sia_directory);
config.set_max_upload_count(0U);
EXPECT_EQ(std::uint8_t(1U), config.get_max_upload_count());
}
}
TEST_F(config_test, online_check_retry_secs) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_online_check_retry_secs();
config.set_online_check_retry_secs(original_value + 1);
EXPECT_EQ(original_value + 1, config.get_online_check_retry_secs());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 1, config.get_online_check_retry_secs());
}
}
TEST_F(config_test, online_check_retry_secs_minimum_value) {
{
app_config config(provider_type::sia, sia_directory);
config.set_online_check_retry_secs(14);
EXPECT_EQ(15, config.get_online_check_retry_secs());
}
}
TEST_F(config_test, orphaned_file_retention_days) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_orphaned_file_retention_days();
config.set_orphaned_file_retention_days(original_value + 1);
EXPECT_EQ(original_value + 1, config.get_orphaned_file_retention_days());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 1, config.get_orphaned_file_retention_days());
}
}
TEST_F(config_test, orphaned_file_retention_days_minimum_value) {
{
app_config config(provider_type::sia, sia_directory);
config.set_orphaned_file_retention_days(0);
EXPECT_EQ(1, config.get_orphaned_file_retention_days());
}
}
TEST_F(config_test, orphaned_file_retention_days_maximum_value) {
{
app_config config(provider_type::sia, sia_directory);
config.set_orphaned_file_retention_days(32);
EXPECT_EQ(31, config.get_orphaned_file_retention_days());
}
}
TEST_F(config_test, get_cache_directory) {
{
app_config config(provider_type::sia, sia_directory);
EXPECT_STREQ(utils::path::combine(sia_directory, {"cache"}).c_str(),
config.get_cache_directory().c_str());
}
}
TEST_F(config_test, get_config_file_path) {
{
const auto config_file = utils::path::absolute(
utils::path::combine(sia_directory, {"config.json"}));
app_config config(provider_type::sia, sia_directory);
EXPECT_STREQ(config_file.c_str(), config.get_config_file_path().c_str());
}
}
TEST_F(config_test, get_data_directory) {
{
app_config config(provider_type::sia, sia_directory);
EXPECT_STREQ(sia_directory.c_str(), config.get_data_directory().c_str());
}
}
TEST_F(config_test, get_log_directory) {
{
app_config config(provider_type::sia, sia_directory);
EXPECT_STREQ(utils::path::combine(sia_directory, {"logs"}).c_str(),
config.get_log_directory().c_str());
}
}
TEST_F(config_test, ring_buffer_file_size) {
std::uint16_t original_value;
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_ring_buffer_file_size();
config.set_ring_buffer_file_size(original_value + 5u);
EXPECT_EQ(original_value + 5u, config.get_ring_buffer_file_size());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5u, config.get_ring_buffer_file_size());
}
}
TEST_F(config_test, ring_buffer_file_size_minimum_size) {
{
app_config config(provider_type::sia, sia_directory);
config.set_ring_buffer_file_size(63u);
EXPECT_EQ(64u, config.get_ring_buffer_file_size());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(64u, config.get_ring_buffer_file_size());
}
}
TEST_F(config_test, ring_buffer_file_size_maximum_size) {
{
app_config config(provider_type::sia, sia_directory);
config.set_ring_buffer_file_size(1025u);
EXPECT_EQ(1024u, config.get_ring_buffer_file_size());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(1024u, config.get_ring_buffer_file_size());
}
}
TEST_F(config_test, preferred_download_type) {
download_type original_value;
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_preferred_download_type();
config.set_preferred_download_type(download_type::ring_buffer);
EXPECT_NE(original_value, config.get_preferred_download_type());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_NE(original_value, config.get_preferred_download_type());
}
}
TEST_F(config_test, default_agent_name) {
EXPECT_STREQ("Sia-Agent",
app_config::default_agent_name(provider_type::sia).c_str());
}
TEST_F(config_test, default_api_port) {
EXPECT_EQ(9980U, app_config::default_api_port(provider_type::sia));
}
TEST_F(config_test, default_data_directory) {
const std::array<std::string, 1U> data_directory = {
app_config::default_data_directory(provider_type::sia),
};
#if defined(_WIN32)
const auto local_app_data = utils::get_environment_variable("localappdata");
#endif
#if defined(__linux__)
const auto local_app_data =
utils::path::combine(utils::get_environment_variable("HOME"), {".local"});
#endif
#if defined(__APPLE__)
const auto local_app_data = utils::path::combine(
utils::get_environment_variable("HOME"), {"Library/Application Support"});
#endif
auto expected_directory =
utils::path::combine(local_app_data, {"/repertory2/sia"});
EXPECT_STREQ(expected_directory.c_str(), data_directory[0].c_str());
}
TEST_F(config_test, default_rpc_port) {
EXPECT_EQ(10000U, app_config::default_rpc_port(provider_type::sia));
}
TEST_F(config_test, get_provider_display_name) {
EXPECT_STREQ(
"Sia", app_config::get_provider_display_name(provider_type::sia).c_str());
}
TEST_F(config_test, get_provider_name) {
EXPECT_STREQ("sia",
app_config::get_provider_name(provider_type::sia).c_str());
}
TEST_F(config_test, get_version) {
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(REPERTORY_CONFIG_VERSION, config.get_version());
}
}
// TEST_F(config_test, enable_remote_mount) {
// bool original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_enable_remote_mount();
// config.set_enable_remote_mount(not original_value);
// EXPECT_EQ(not original_value, config.get_enable_remote_mount());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(not original_value, config.get_enable_remote_mount());
// }
// }
// TEST_F(config_test, is_remote_mount) {
// bool original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_is_remote_mount();
// config.set_is_remote_mount(not original_value);
// EXPECT_EQ(not original_value, config.get_is_remote_mount());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(not original_value, config.get_is_remote_mount());
// }
// }
// TEST_F(config_test, enable_remote_mount_fails_if_remote_mount_is_true) {
// app_config config(provider_type::sia, sia_directory);
// config.set_is_remote_mount(true);
// config.set_enable_remote_mount(true);
// EXPECT_FALSE(config.get_enable_remote_mount());
// EXPECT_TRUE(config.get_is_remote_mount());
// }
// TEST_F(config_test, set_is_remote_mount_fails_if_enable_remote_mount_is_true)
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_enable_remote_mount(true);
// config.set_is_remote_mount(true);
// EXPECT_FALSE(config.get_is_remote_mount());
// EXPECT_TRUE(config.get_enable_remote_mount());
// }
// TEST_F(config_test, remote_host_name_or_ip) {
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_remote_host_name_or_ip("my.host.name");
// EXPECT_STREQ("my.host.name",
// config.get_remote_host_name_or_ip().c_str());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_STREQ("my.host.name",
// config.get_remote_host_name_or_ip().c_str());
// }
// }
// TEST_F(config_test, remote_api_port) {
// std::uint16_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_api_port();
// config.set_remote_api_port(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_api_port());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_api_port());
// }
// }
// TEST_F(config_test, remote_receive_timeout_secs) {
// std::uint16_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_receive_timeout_secs();
// config.set_remote_receive_timeout_secs(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_receive_timeout_secs());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_receive_timeout_secs());
// }
// }
// TEST_F(config_test, remote_send_timeout_secs) {
// std::uint16_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_send_timeout_secs();
// config.set_remote_send_timeout_secs(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_send_timeout_secs());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_send_timeout_secs());
// }
// }
// TEST_F(config_test, remote_encryption_token) {
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_remote_encryption_token("myToken");
// EXPECT_STREQ("myToken", config.get_remote_encryption_token().c_str());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_STREQ("myToken", config.get_remote_encryption_token().c_str());
// }
// }
//
// TEST_F(config_test, remote_client_pool_size) {
// std::uint8_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_client_pool_size();
// config.set_remote_client_pool_size(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_client_pool_size());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_client_pool_size());
// }
// }
//
// TEST_F(config_test, remote_client_pool_size_minimum_value) {
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_remote_client_pool_size(0);
// EXPECT_EQ(5, config.get_remote_client_pool_size());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(5, config.get_remote_client_pool_size());
// }
// }
// TEST_F(config_test, remote_max_connections) {
// std::uint8_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_max_connections();
// config.set_remote_max_connections(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_max_connections());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_max_connections());
// }
// }
// TEST_F(config_test, remote_max_connections_minimum_value) {
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_remote_max_connections(0);
// EXPECT_EQ(1, config.get_remote_max_connections());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(1, config.get_remote_max_connections());
// }
// }
TEST_F(config_test, retry_read_count) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_retry_read_count();
config.set_retry_read_count(original_value + 1);
EXPECT_EQ(original_value + 1, config.get_retry_read_count());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 1, config.get_retry_read_count());
}
}
TEST_F(config_test, retry_read_count_minimum_value) {
{
app_config config(provider_type::sia, sia_directory);
config.set_retry_read_count(1);
EXPECT_EQ(2, config.get_retry_read_count());
}
}
TEST_F(config_test, task_wait_ms) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_task_wait_ms();
config.set_task_wait_ms(original_value + 1U);
EXPECT_EQ(original_value + 1U, config.get_task_wait_ms());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 1U, config.get_task_wait_ms());
}
}
TEST_F(config_test, task_wait_ms_minimum_value) {
{
app_config config(provider_type::sia, sia_directory);
config.set_task_wait_ms(1U);
EXPECT_EQ(50U, config.get_task_wait_ms());
}
}
TEST_F(config_test, can_set_database_type) {
{
app_config config(provider_type::sia, sia_directory);
config.set_database_type(database_type::rocksdb);
EXPECT_EQ(database_type::rocksdb, config.get_database_type());
config.set_database_type(database_type::sqlite);
EXPECT_EQ(database_type::sqlite, config.get_database_type());
config.set_database_type(database_type::rocksdb);
EXPECT_EQ(database_type::rocksdb, config.get_database_type());
}
}
} // namespace repertory

View File

@ -25,7 +25,7 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
namespace repertory { namespace repertory {
TEST(curl_comm_test, can_create_s3_host_config) { TEST(curl_comm, can_create_s3_host_config) {
s3_config config{}; s3_config config{};
config.bucket = "repertory"; config.bucket = "repertory";
config.url = "https://s3.test.com"; config.url = "https://s3.test.com";
@ -37,7 +37,7 @@ TEST(curl_comm_test, can_create_s3_host_config) {
EXPECT_TRUE(hc.path.empty()); EXPECT_TRUE(hc.path.empty());
} }
TEST(curl_comm_test, can_create_s3_host_config_with_path_style) { TEST(curl_comm, can_create_s3_host_config_with_path_style) {
s3_config config{}; s3_config config{};
config.bucket = "repertory"; config.bucket = "repertory";
config.url = "https://s3.test.com"; config.url = "https://s3.test.com";
@ -49,7 +49,7 @@ TEST(curl_comm_test, can_create_s3_host_config_with_path_style) {
EXPECT_STREQ("/repertory", hc.path.c_str()); EXPECT_STREQ("/repertory", hc.path.c_str());
} }
TEST(curl_comm_test, can_create_s3_host_config_with_region) { TEST(curl_comm, can_create_s3_host_config_with_region) {
s3_config config{}; s3_config config{};
config.bucket = "repertory"; config.bucket = "repertory";
config.url = "https://s3.test.com"; config.url = "https://s3.test.com";
@ -62,7 +62,7 @@ TEST(curl_comm_test, can_create_s3_host_config_with_region) {
EXPECT_TRUE(hc.path.empty()); EXPECT_TRUE(hc.path.empty());
} }
TEST(curl_comm_test, can_create_s3_host_config_with_region_and_path_style) { TEST(curl_comm, can_create_s3_host_config_with_region_and_path_style) {
s3_config config{}; s3_config config{};
config.bucket = "repertory"; config.bucket = "repertory";
config.url = "https://s3.test.com"; config.url = "https://s3.test.com";

View File

@ -25,7 +25,7 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
namespace repertory { namespace repertory {
TEST(json_serialize_test, can_handle_directory_item) { TEST(json_serialize, can_handle_directory_item) {
directory_item cfg{ directory_item cfg{
"api", "parent", true, 2U, {{META_DIRECTORY, "true"}}, "api", "parent", true, 2U, {{META_DIRECTORY, "true"}},
}; };
@ -47,7 +47,7 @@ TEST(json_serialize_test, can_handle_directory_item) {
} }
} }
TEST(json_serialize_test, can_handle_encrypt_config) { TEST(json_serialize, can_handle_encrypt_config) {
encrypt_config cfg{ encrypt_config cfg{
"token", "token",
"path", "path",
@ -65,7 +65,7 @@ TEST(json_serialize_test, can_handle_encrypt_config) {
} }
} }
TEST(json_serialize_test, can_handle_host_config) { TEST(json_serialize, can_handle_host_config) {
host_config cfg{ host_config cfg{
"agent", "pwd", "user", 1024U, "host", "path", "http", 11U, "agent", "pwd", "user", 1024U, "host", "path", "http", 11U,
}; };
@ -94,7 +94,7 @@ TEST(json_serialize_test, can_handle_host_config) {
} }
} }
TEST(json_serialize_test, can_handle_remote_config) { TEST(json_serialize, can_handle_remote_config) {
remote::remote_config cfg{ remote::remote_config cfg{
1024U, "token", "host", 11U, 20U, 21U, 1024U, "token", "host", 11U, 20U, 21U,
}; };
@ -120,7 +120,7 @@ TEST(json_serialize_test, can_handle_remote_config) {
} }
} }
TEST(json_serialize_test, can_handle_remote_mount) { TEST(json_serialize, can_handle_remote_mount) {
remote::remote_mount cfg{1024U, 21U, true, "token"}; remote::remote_mount cfg{1024U, 21U, true, "token"};
json data(cfg); json data(cfg);
@ -139,7 +139,7 @@ TEST(json_serialize_test, can_handle_remote_mount) {
} }
} }
TEST(json_serialize_test, can_handle_s3_config) { TEST(json_serialize, can_handle_s3_config) {
s3_config cfg{ s3_config cfg{
"access", "bucket", "token", "region", "secret", 31U, "url", true, false, "access", "bucket", "token", "region", "secret", 31U, "url", true, false,
}; };
@ -170,7 +170,7 @@ TEST(json_serialize_test, can_handle_s3_config) {
} }
} }
TEST(json_serialize_test, can_handle_sia_config) { TEST(json_serialize, can_handle_sia_config) {
sia_config cfg{ sia_config cfg{
"bucket", "bucket",
}; };
@ -184,7 +184,7 @@ TEST(json_serialize_test, can_handle_sia_config) {
} }
} }
TEST(json_serialize_test, can_handle_atomic) { TEST(json_serialize, can_handle_atomic) {
atomic<sia_config> cfg({ atomic<sia_config> cfg({
"bucket", "bucket",
}); });
@ -198,7 +198,7 @@ TEST(json_serialize_test, can_handle_atomic) {
} }
} }
TEST(json_serialize_test, can_handle_database_type) { TEST(json_serialize, can_handle_database_type) {
json data(database_type::rocksdb); json data(database_type::rocksdb);
EXPECT_EQ(database_type::rocksdb, data.get<database_type>()); EXPECT_EQ(database_type::rocksdb, data.get<database_type>());
EXPECT_STREQ("rocksdb", data.get<std::string>().c_str()); EXPECT_STREQ("rocksdb", data.get<std::string>().c_str());
@ -208,7 +208,7 @@ TEST(json_serialize_test, can_handle_database_type) {
EXPECT_STREQ("sqlite", data.get<std::string>().c_str()); EXPECT_STREQ("sqlite", data.get<std::string>().c_str());
} }
TEST(json_serialize_test, can_handle_download_type) { TEST(json_serialize, can_handle_download_type) {
json data(download_type::direct); json data(download_type::direct);
EXPECT_EQ(download_type::direct, data.get<download_type>()); EXPECT_EQ(download_type::direct, data.get<download_type>());
EXPECT_STREQ("direct", data.get<std::string>().c_str()); EXPECT_STREQ("direct", data.get<std::string>().c_str());
@ -222,33 +222,7 @@ TEST(json_serialize_test, can_handle_download_type) {
EXPECT_STREQ("ring_buffer", data.get<std::string>().c_str()); EXPECT_STREQ("ring_buffer", data.get<std::string>().c_str());
} }
TEST(json_serialize_test, can_handle_event_level) { TEST(json_serialize, can_handle_atomic_database_type) {
json data(event_level{event_level::critical});
EXPECT_EQ(event_level::critical, data.get<event_level>());
EXPECT_STREQ("critical", data.get<std::string>().c_str());
data = event_level(event_level::error);
EXPECT_EQ(event_level::error, data.get<event_level>());
EXPECT_STREQ("error", data.get<std::string>().c_str());
data = event_level(event_level::warn);
EXPECT_EQ(event_level::warn, data.get<event_level>());
EXPECT_STREQ("warn", data.get<std::string>().c_str());
data = event_level(event_level::info);
EXPECT_EQ(event_level::info, data.get<event_level>());
EXPECT_STREQ("info", data.get<std::string>().c_str());
data = event_level(event_level::debug);
EXPECT_EQ(event_level::debug, data.get<event_level>());
EXPECT_STREQ("debug", data.get<std::string>().c_str());
data = event_level(event_level::trace);
EXPECT_EQ(event_level::trace, data.get<event_level>());
EXPECT_STREQ("trace", data.get<std::string>().c_str());
}
TEST(json_serialize_test, can_handle_atomic_database_type) {
json data(atomic<database_type>{database_type::rocksdb}); json data(atomic<database_type>{database_type::rocksdb});
EXPECT_EQ(database_type::rocksdb, data.get<atomic<database_type>>()); EXPECT_EQ(database_type::rocksdb, data.get<atomic<database_type>>());
EXPECT_STREQ("rocksdb", data.get<std::string>().c_str()); EXPECT_STREQ("rocksdb", data.get<std::string>().c_str());
@ -258,7 +232,7 @@ TEST(json_serialize_test, can_handle_atomic_database_type) {
EXPECT_STREQ("sqlite", data.get<std::string>().c_str()); EXPECT_STREQ("sqlite", data.get<std::string>().c_str());
} }
TEST(json_serialize_test, can_handle_atomic_download_type) { TEST(json_serialize, can_handle_atomic_download_type) {
json data(atomic<download_type>{download_type::direct}); json data(atomic<download_type>{download_type::direct});
EXPECT_EQ(download_type::direct, data.get<atomic<download_type>>()); EXPECT_EQ(download_type::direct, data.get<atomic<download_type>>());
EXPECT_STREQ("direct", data.get<std::string>().c_str()); EXPECT_STREQ("direct", data.get<std::string>().c_str());
@ -271,30 +245,4 @@ TEST(json_serialize_test, can_handle_atomic_download_type) {
EXPECT_EQ(download_type::ring_buffer, data.get<atomic<download_type>>()); EXPECT_EQ(download_type::ring_buffer, data.get<atomic<download_type>>());
EXPECT_STREQ("ring_buffer", data.get<std::string>().c_str()); EXPECT_STREQ("ring_buffer", data.get<std::string>().c_str());
} }
TEST(json_serialize_test, can_handle_atomic_event_level) {
json data(atomic<event_level>{event_level::critical});
EXPECT_EQ(event_level::critical, data.get<atomic<event_level>>());
EXPECT_STREQ("critical", data.get<std::string>().c_str());
data = atomic<event_level>(event_level::error);
EXPECT_EQ(event_level::error, data.get<atomic<event_level>>());
EXPECT_STREQ("error", data.get<std::string>().c_str());
data = atomic<event_level>(event_level::warn);
EXPECT_EQ(event_level::warn, data.get<atomic<event_level>>());
EXPECT_STREQ("warn", data.get<std::string>().c_str());
data = atomic<event_level>(event_level::info);
EXPECT_EQ(event_level::info, data.get<atomic<event_level>>());
EXPECT_STREQ("info", data.get<std::string>().c_str());
data = atomic<event_level>(event_level::debug);
EXPECT_EQ(event_level::debug, data.get<atomic<event_level>>());
EXPECT_STREQ("debug", data.get<std::string>().c_str());
data = atomic<event_level>(event_level::trace);
EXPECT_EQ(event_level::trace, data.get<atomic<event_level>>());
EXPECT_STREQ("trace", data.get<std::string>().c_str());
}
} // namespace repertory } // namespace repertory

View File

@ -24,7 +24,7 @@
#include "platform/platform.hpp" #include "platform/platform.hpp"
namespace repertory { namespace repertory {
TEST(lock_data_test, lock_and_unlock) { TEST(lock_data, lock_and_unlock) {
{ {
lock_data l(provider_type::sia, "1"); lock_data l(provider_type::sia, "1");
EXPECT_EQ(lock_result::success, l.grab_lock()); EXPECT_EQ(lock_result::success, l.grab_lock());
@ -50,7 +50,7 @@ TEST(lock_data_test, lock_and_unlock) {
} }
#if defined(_WIN32) #if defined(_WIN32)
TEST(lock_data_test, set_and_unset_mount_state) { TEST(lock_data, set_and_unset_mount_state) {
lock_data l(provider_type::sia, "1"); lock_data l(provider_type::sia, "1");
EXPECT_TRUE(l.set_mount_state(true, "C:", 99)); EXPECT_TRUE(l.set_mount_state(true, "C:", 99));
@ -83,7 +83,7 @@ TEST(lock_data_test, set_and_unset_mount_state) {
mount_state["Remote2"].dump().c_str()); mount_state["Remote2"].dump().c_str());
} }
#else #else
TEST(lock_data_test, set_and_unset_mount_state) { TEST(lock_data, set_and_unset_mount_state) {
lock_data l(provider_type::sia, "1"); lock_data l(provider_type::sia, "1");
EXPECT_TRUE(l.set_mount_state(true, "/mnt/1", 99)); EXPECT_TRUE(l.set_mount_state(true, "/mnt/1", 99));

View File

@ -24,7 +24,7 @@
#include "comm/packet/packet.hpp" #include "comm/packet/packet.hpp"
namespace repertory { namespace repertory {
TEST(packet_test, encrypt_and_decrypt) { TEST(packet, encrypt_and_decrypt) {
packet test_packet; packet test_packet;
test_packet.encode("test"); test_packet.encode("test");
test_packet.encrypt("moose"); test_packet.encrypt("moose");

View File

@ -19,6 +19,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#if 0
#include "test_common.hpp" #include "test_common.hpp"
#include "comm/curl/curl_comm.hpp" #include "comm/curl/curl_comm.hpp"
@ -97,6 +99,8 @@ const auto create_directory = [](repertory::i_provider &provider,
repertory::utils::string::to_bool(meta2[repertory::META_PINNED])); repertory::utils::string::to_bool(meta2[repertory::META_PINNED]));
EXPECT_EQ(std::uint64_t(0U), EXPECT_EQ(std::uint64_t(0U),
repertory::utils::string::to_uint64(meta2[repertory::META_SIZE])); repertory::utils::string::to_uint64(meta2[repertory::META_SIZE]));
EXPECT_STREQ((api_path + "_src").c_str(),
meta2[repertory::META_SOURCE].c_str());
EXPECT_EQ(getuid(), static_cast<uid_t>(repertory::utils::string::to_uint32( EXPECT_EQ(getuid(), static_cast<uid_t>(repertory::utils::string::to_uint32(
meta2[repertory::META_UID]))); meta2[repertory::META_UID])));
EXPECT_EQ(date + 4U, repertory::utils::string::to_uint64( EXPECT_EQ(date + 4U, repertory::utils::string::to_uint64(
@ -174,9 +178,6 @@ const auto decrypt_parts = [](const repertory::app_config &cfg,
namespace repertory { namespace repertory {
static void can_create_and_remove_directory(i_provider &provider) { static void can_create_and_remove_directory(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
api_meta_map meta{}; api_meta_map meta{};
EXPECT_EQ(api_error::not_implemented, EXPECT_EQ(api_error::not_implemented,
@ -195,9 +196,6 @@ static void can_create_and_remove_directory(i_provider &provider) {
} }
static void create_directory_fails_if_already_exists(i_provider &provider) { static void create_directory_fails_if_already_exists(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
return; return;
} }
@ -212,9 +210,6 @@ static void create_directory_fails_if_already_exists(i_provider &provider) {
static void static void
create_directory_fails_if_file_already_exists(i_provider &provider) { create_directory_fails_if_file_already_exists(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
return; return;
} }
@ -228,9 +223,6 @@ create_directory_fails_if_file_already_exists(i_provider &provider) {
} }
static void create_directory_clone_source_meta(i_provider &provider) { static void create_directory_clone_source_meta(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
EXPECT_EQ(api_error::not_implemented, EXPECT_EQ(api_error::not_implemented,
provider.create_directory_clone_source_meta("/moose", "/moose")); provider.create_directory_clone_source_meta("/moose", "/moose"));
@ -265,9 +257,6 @@ static void create_directory_clone_source_meta(i_provider &provider) {
static void create_directory_clone_source_meta_fails_if_already_exists( static void create_directory_clone_source_meta_fails_if_already_exists(
i_provider &provider) { i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
return; return;
} }
@ -283,9 +272,6 @@ static void create_directory_clone_source_meta_fails_if_already_exists(
static void create_directory_clone_source_meta_fails_if_directory_not_found( static void create_directory_clone_source_meta_fails_if_directory_not_found(
i_provider &provider) { i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
return; return;
} }
@ -296,9 +282,6 @@ static void create_directory_clone_source_meta_fails_if_directory_not_found(
static void create_directory_clone_source_meta_fails_if_file_already_exists( static void create_directory_clone_source_meta_fails_if_file_already_exists(
i_provider &provider) { i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
return; return;
} }
@ -314,9 +297,6 @@ static void create_directory_clone_source_meta_fails_if_file_already_exists(
} }
static void can_create_and_remove_file(i_provider &provider) { static void can_create_and_remove_file(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
api_meta_map meta{}; api_meta_map meta{};
EXPECT_EQ(api_error::not_implemented, EXPECT_EQ(api_error::not_implemented,
@ -337,9 +317,6 @@ static void can_create_and_remove_file(i_provider &provider) {
} }
static void create_file_fails_if_already_exists(i_provider &provider) { static void create_file_fails_if_already_exists(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
return; return;
} }
@ -354,9 +331,6 @@ static void create_file_fails_if_already_exists(i_provider &provider) {
static void static void
create_file_fails_if_directory_already_exists(i_provider &provider) { create_file_fails_if_directory_already_exists(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.is_read_only()) { if (provider.is_read_only()) {
return; return;
} }
@ -371,12 +345,9 @@ create_file_fails_if_directory_already_exists(i_provider &provider) {
static void get_api_path_from_source(const app_config &cfg, static void get_api_path_from_source(const app_config &cfg,
i_provider &provider) { i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.get_provider_type() == provider_type::encrypt) { if (provider.get_provider_type() == provider_type::encrypt) {
auto source_path = const auto source_path =
utils::path::combine("./test_input/encrypt", {"test.txt"}); utils::path::combine("./test_date/encrypt", {"test.txt"});
std::string api_path{}; std::string api_path{};
EXPECT_EQ(api_error::success, EXPECT_EQ(api_error::success,
@ -405,9 +376,6 @@ static void get_api_path_from_source(const app_config &cfg,
static void static void
get_api_path_from_source_fails_if_file_not_found(const app_config &cfg, get_api_path_from_source_fails_if_file_not_found(const app_config &cfg,
i_provider &provider) { i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
std::string source_path{}; std::string source_path{};
if (provider.get_provider_type() == provider_type::encrypt) { if (provider.get_provider_type() == provider_type::encrypt) {
source_path = utils::path::combine(cfg.get_encrypt_config().path, source_path = utils::path::combine(cfg.get_encrypt_config().path,
@ -423,50 +391,28 @@ get_api_path_from_source_fails_if_file_not_found(const app_config &cfg,
EXPECT_TRUE(api_path.empty()); EXPECT_TRUE(api_path.empty());
} }
static void get_directory_item_count(const app_config & /* cfg */, static void get_directory_item_count(const app_config &cfg,
i_provider &provider) { i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.get_provider_type() == provider_type::encrypt) { if (provider.get_provider_type() == provider_type::encrypt) {
EXPECT_EQ(std::size_t(2U), provider.get_directory_item_count("/")); EXPECT_EQ(std::size_t(2U), provider.get_directory_item_count("/"));
EXPECT_EQ(std::size_t(0U), provider.get_directory_item_count("/not_found")); EXPECT_EQ(std::size_t(0U), provider.get_directory_item_count("/not_found"));
auto source_path = const auto source_path =
utils::path::combine(test::get_test_input_dir(), {"encrypt", "sub10"}); utils::path::combine(test::get_test_input_dir(), {"encrypt", "sub10"});
std::string api_path{}; std::string api_path{};
EXPECT_EQ(api_error::success, EXPECT_EQ(api_error::success,
provider.get_api_path_from_source(source_path, api_path)); provider.get_api_path_from_source(source_path, api_path));
EXPECT_EQ(std::size_t(1U), provider.get_directory_item_count(api_path)); EXPECT_EQ(std::size_t(1U), provider.get_directory_item_count(api_path));
return;
} }
create_file(provider, "/pt01.txt");
create_file(provider, "/pt02.txt");
create_directory(provider, "/dir01");
create_directory(provider, "/dir02");
directory_item_list list{};
EXPECT_EQ(api_error::success, provider.get_directory_items("/", list));
check_forced_dirs(list);
EXPECT_GE(list.size(), std::size_t(6U));
EXPECT_EQ(api_error::success, provider.remove_file("/pt01.txt"));
EXPECT_EQ(api_error::success, provider.remove_file("/pt02.txt"));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir01"));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir02"));
} }
static void get_directory_items(const app_config &cfg, i_provider &provider) { static void get_directory_items(const app_config &cfg, i_provider &provider) {
fmt::println("testing|{}|{}", directory_item_list list{};
app_config::get_provider_name(provider.get_provider_type()), EXPECT_EQ(api_error::success, provider.get_directory_items("/", list));
__FUNCTION__); check_forced_dirs(list);
if (provider.get_provider_type() == provider_type::encrypt) {
directory_item_list list{};
EXPECT_EQ(api_error::success, provider.get_directory_items("/", list));
check_forced_dirs(list);
if (provider.get_provider_type() == provider_type::encrypt) {
EXPECT_EQ(std::size_t(4U), list.size()); EXPECT_EQ(std::size_t(4U), list.size());
directory_item_list list_decrypted{list.begin() + 2U, list.end()}; directory_item_list list_decrypted{list.begin() + 2U, list.end()};
@ -497,7 +443,7 @@ static void get_directory_items(const app_config &cfg, i_provider &provider) {
EXPECT_EQ(std::size_t(46U), file->size); EXPECT_EQ(std::size_t(46U), file->size);
#endif #endif
auto source_path = const auto source_path =
utils::path::combine(cfg.get_encrypt_config().path, {"sub10"}); utils::path::combine(cfg.get_encrypt_config().path, {"sub10"});
std::string api_path{}; std::string api_path{};
EXPECT_EQ(api_error::success, EXPECT_EQ(api_error::success,
@ -526,58 +472,11 @@ static void get_directory_items(const app_config &cfg, i_provider &provider) {
#else #else
EXPECT_EQ(std::size_t(45U), file2->size); EXPECT_EQ(std::size_t(45U), file2->size);
#endif #endif
return;
} }
create_file(provider, "/pt01.txt");
create_file(provider, "/pt02.txt");
create_directory(provider, "/dir01");
create_directory(provider, "/dir02");
directory_item_list list{};
EXPECT_EQ(api_error::success, provider.get_directory_items("/", list));
check_forced_dirs(list);
EXPECT_GE(list.size(), std::size_t(6U));
auto iter = std::ranges::find_if(
list, [](auto &&item) -> bool { return item.api_path == "/pt01.txt"; });
EXPECT_NE(iter, list.end());
EXPECT_STREQ("/", (*iter).api_parent.c_str());
EXPECT_FALSE((*iter).directory);
EXPECT_EQ(std::uint64_t{0U}, (*iter).size);
iter = std::ranges::find_if(
list, [](auto &&item) -> bool { return item.api_path == "/pt02.txt"; });
EXPECT_NE(iter, list.end());
EXPECT_STREQ("/", (*iter).api_parent.c_str());
EXPECT_FALSE((*iter).directory);
EXPECT_EQ(std::uint64_t{0U}, (*iter).size);
iter = std::ranges::find_if(
list, [](auto &&item) -> bool { return item.api_path == "/dir01"; });
EXPECT_NE(iter, list.end());
EXPECT_STREQ("/", (*iter).api_parent.c_str());
EXPECT_TRUE((*iter).directory);
EXPECT_EQ(std::uint64_t{0U}, (*iter).size);
iter = std::ranges::find_if(
list, [](auto &&item) -> bool { return item.api_path == "/dir02"; });
EXPECT_NE(iter, list.end());
EXPECT_STREQ("/", (*iter).api_parent.c_str());
EXPECT_TRUE((*iter).directory);
EXPECT_EQ(std::uint64_t{0U}, (*iter).size);
EXPECT_EQ(api_error::success, provider.remove_file("/pt01.txt"));
EXPECT_EQ(api_error::success, provider.remove_file("/pt02.txt"));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir01"));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir02"));
} }
static void static void
get_directory_items_fails_if_directory_not_found(i_provider &provider) { get_directory_items_fails_if_directory_not_found(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
directory_item_list list{}; directory_item_list list{};
EXPECT_EQ(api_error::directory_not_found, EXPECT_EQ(api_error::directory_not_found,
provider.get_directory_items("/not_found", list)); provider.get_directory_items("/not_found", list));
@ -586,11 +485,8 @@ get_directory_items_fails_if_directory_not_found(i_provider &provider) {
static void get_directory_items_fails_if_item_is_file(const app_config &cfg, static void get_directory_items_fails_if_item_is_file(const app_config &cfg,
i_provider &provider) { i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.get_provider_type() == provider_type::encrypt) { if (provider.get_provider_type() == provider_type::encrypt) {
auto source_path = const auto source_path =
utils::path::combine(cfg.get_encrypt_config().path, {"test.txt"}); utils::path::combine(cfg.get_encrypt_config().path, {"test.txt"});
std::string api_path{}; std::string api_path{};
@ -601,24 +497,12 @@ static void get_directory_items_fails_if_item_is_file(const app_config &cfg,
EXPECT_EQ(api_error::item_exists, EXPECT_EQ(api_error::item_exists,
provider.get_directory_items(api_path, list)); provider.get_directory_items(api_path, list));
EXPECT_TRUE(list.empty()); EXPECT_TRUE(list.empty());
return;
} }
create_file(provider, "/pt01.txt");
directory_item_list list{};
EXPECT_EQ(api_error::item_exists,
provider.get_directory_items("/pt01.txt", list));
EXPECT_EQ(api_error::success, provider.remove_file("/pt01.txt"));
} }
static void get_file(const app_config &cfg, i_provider &provider) { static void get_file(const app_config &cfg, i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.get_provider_type() == provider_type::encrypt) { if (provider.get_provider_type() == provider_type::encrypt) {
auto source_path = const auto source_path =
utils::path::combine(cfg.get_encrypt_config().path, {"test.txt"}); utils::path::combine(cfg.get_encrypt_config().path, {"test.txt"});
std::string api_path{}; std::string api_path{};
@ -638,43 +522,18 @@ static void get_file(const app_config &cfg, i_provider &provider) {
EXPECT_EQ(std::size_t(46U), file.file_size); EXPECT_EQ(std::size_t(46U), file.file_size);
#endif #endif
EXPECT_STREQ(source_path.c_str(), file.source_path.c_str()); EXPECT_STREQ(source_path.c_str(), file.source_path.c_str());
return;
} }
create_file(provider, "/pt01.txt");
api_file file{};
EXPECT_EQ(api_error::success, provider.get_file("/pt01.txt", file));
EXPECT_STREQ("/pt01.txt", file.api_path.c_str());
EXPECT_STREQ("/", file.api_parent.c_str());
EXPECT_LT(utils::time::get_time_now() - (utils::time::NANOS_PER_SECOND * 5U),
file.accessed_date);
EXPECT_LT(utils::time::get_time_now() - (utils::time::NANOS_PER_SECOND * 5U),
file.changed_date);
EXPECT_LT(utils::time::get_time_now() - (utils::time::NANOS_PER_SECOND * 5U),
file.creation_date);
EXPECT_LT(utils::time::get_time_now() - (utils::time::NANOS_PER_SECOND * 5U),
file.modified_date);
EXPECT_EQ(api_error::success, provider.remove_file("/pt01.txt"));
} }
static void get_file_fails_if_file_not_found(i_provider &provider) { static void get_file_fails_if_file_not_found(i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
api_file file{}; api_file file{};
EXPECT_EQ(api_error::item_not_found, provider.get_file("/not_found", file)); EXPECT_EQ(api_error::item_not_found, provider.get_file("/not_found", file));
} }
static void get_file_fails_if_item_is_directory(const app_config &cfg, static void get_file_fails_if_item_is_directory(const app_config &cfg,
i_provider &provider) { i_provider &provider) {
fmt::println("testing|{}|{}",
app_config::get_provider_name(provider.get_provider_type()),
__FUNCTION__);
if (provider.get_provider_type() == provider_type::encrypt) { if (provider.get_provider_type() == provider_type::encrypt) {
auto source_path = const auto source_path =
utils::path::combine(cfg.get_encrypt_config().path, {"sub10"}); utils::path::combine(cfg.get_encrypt_config().path, {"sub10"});
std::string api_path{}; std::string api_path{};
@ -683,15 +542,7 @@ static void get_file_fails_if_item_is_directory(const app_config &cfg,
api_file file{}; api_file file{};
EXPECT_EQ(api_error::directory_exists, provider.get_file(api_path, file)); EXPECT_EQ(api_error::directory_exists, provider.get_file(api_path, file));
return;
} }
create_directory(provider, "/dir01");
api_file file{};
EXPECT_EQ(api_error::directory_exists, provider.get_file("/dir01", file));
EXPECT_EQ(api_error::success, provider.remove_directory("/dir01"));
} }
static void get_file_list(const app_config &cfg, i_provider &provider) { static void get_file_list(const app_config &cfg, i_provider &provider) {
@ -742,6 +593,7 @@ static void run_tests(const app_config &cfg, i_provider &provider) {
get_api_path_from_source(cfg, provider); get_api_path_from_source(cfg, provider);
get_api_path_from_source_fails_if_file_not_found(cfg, provider); get_api_path_from_source_fails_if_file_not_found(cfg, provider);
// TODO: continue here
get_directory_items(cfg, provider); get_directory_items(cfg, provider);
get_directory_items_fails_if_directory_not_found(provider); get_directory_items_fails_if_directory_not_found(provider);
get_directory_items_fails_if_item_is_file(cfg, provider); get_directory_items_fails_if_item_is_file(cfg, provider);
@ -777,16 +629,17 @@ static void run_tests(const app_config &cfg, i_provider &provider) {
upload_file(provider); */ upload_file(provider); */
} }
TEST(providers_test, encrypt_provider) { TEST(providers, encrypt_provider) {
auto config_path = utils::path::combine(test::get_test_output_dir(), const auto config_path =
{"provider", "encrypt"}); utils::path::combine(test::get_test_output_dir(), {"encrypt_provider"});
console_consumer consumer{}; console_consumer consumer{};
event_system::instance().start(); event_system::instance().start();
{ {
app_config cfg(provider_type::encrypt, config_path); app_config cfg(provider_type::encrypt, config_path);
auto encrypt_path = const auto encrypt_path =
utils::path::combine(test::get_test_input_dir(), {"encrypt"}); utils::path::combine(test::get_test_input_dir(), {"encrypt"});
EXPECT_STREQ( EXPECT_STREQ(
@ -820,9 +673,9 @@ TEST(providers_test, encrypt_provider) {
event_system::instance().stop(); event_system::instance().stop();
} }
TEST(providers_test, s3_provider) { TEST(providers, s3_provider) {
auto config_path = const auto config_path =
utils::path::combine(test::get_test_output_dir(), {"provider", "s3"}); utils::path::combine(test::get_test_output_dir(), {"s3_provider"});
console_consumer consumer{}; console_consumer consumer{};
event_system::instance().start(); event_system::instance().start();
@ -832,7 +685,7 @@ TEST(providers_test, s3_provider) {
{ {
app_config src_cfg( app_config src_cfg(
provider_type::s3, provider_type::s3,
utils::path::combine(test::get_test_config_dir(), {"s3"})); utils::path::combine(test::get_test_config_dir(), {"storj"}));
cfg.set_s3_config(src_cfg.get_s3_config()); cfg.set_s3_config(src_cfg.get_s3_config());
} }
@ -860,9 +713,9 @@ TEST(providers_test, s3_provider) {
event_system::instance().stop(); event_system::instance().stop();
} }
TEST(providers_test, sia_provider) { TEST(providers, sia_provider) {
auto config_path = const auto config_path =
utils::path::combine(test::get_test_output_dir(), {"sia", "provider"}); utils::path::combine(test::get_test_output_dir(), {"sia_provider"});
console_consumer consumer{}; console_consumer consumer{};
event_system::instance().start(); event_system::instance().start();
@ -900,3 +753,5 @@ TEST(providers_test, sia_provider) {
event_system::instance().stop(); event_system::instance().stop();
} }
} // namespace repertory } // namespace repertory
#endif // 0

View File

@ -29,7 +29,7 @@
namespace repertory { namespace repertory {
static constexpr const std::size_t test_chunk_size{1024U}; static constexpr const std::size_t test_chunk_size{1024U};
TEST(upload_test, can_upload_a_valid_file) { TEST(upload, can_upload_a_valid_file) {
console_consumer con; console_consumer con;
event_system::instance().start(); event_system::instance().start();
@ -71,7 +71,7 @@ TEST(upload_test, can_upload_a_valid_file) {
event_system::instance().stop(); event_system::instance().stop();
} }
TEST(upload_test, can_cancel_upload) { TEST(upload, can_cancel_upload) {
console_consumer con; console_consumer con;
event_system::instance().start(); event_system::instance().start();
@ -135,7 +135,7 @@ TEST(upload_test, can_cancel_upload) {
event_system::instance().stop(); event_system::instance().stop();
} }
TEST(upload_test, can_stop_upload) { TEST(upload, can_stop_upload) {
console_consumer con; console_consumer con;
event_system::instance().start(); event_system::instance().start();

View File

@ -25,7 +25,7 @@
#include "utils/file.hpp" #include "utils/file.hpp"
namespace repertory { namespace repertory {
TEST(utils_test, convert_api_date) { TEST(utils, convert_api_date) {
#if defined(_WIN32) #if defined(_WIN32)
auto file_time = utils::time::unix_time_to_filetime( auto file_time = utils::time::unix_time_to_filetime(
s3_provider::convert_api_date("2009-10-12T17:50:30.111Z")); s3_provider::convert_api_date("2009-10-12T17:50:30.111Z"));
@ -63,7 +63,7 @@ TEST(utils_test, convert_api_date) {
#endif // defined(_WIN32) #endif // defined(_WIN32)
} }
TEST(utils_test, generate_sha256) { TEST(utils, generate_sha256) {
auto res = utils::file::file{__FILE__}.sha256(); auto res = utils::file::file{__FILE__}.sha256();
EXPECT_TRUE(res.has_value()); EXPECT_TRUE(res.has_value());
if (res.has_value()) { if (res.has_value()) {

View File

@ -42,7 +42,6 @@ done
PROJECT_APP_LIST=() PROJECT_APP_LIST=()
PROJECT_CMAKE_OPTS="" PROJECT_CMAKE_OPTS=""
PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF PROJECT_ENABLE_WIN32_LONG_PATH_NAMES=OFF
PROJECT_ENABLE_V2_ERRORS=OFF
PROJECT_IS_ALPINE=0 PROJECT_IS_ALPINE=0
PROJECT_IS_ARM64=0 PROJECT_IS_ARM64=0
PROJECT_MINGW64_COPY_DEPENDENCIES=() PROJECT_MINGW64_COPY_DEPENDENCIES=()
@ -235,7 +234,6 @@ PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_DIR=${PROJECT_BUILD_DIR} ${PROJECT_CMAKE_OPT
PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS} ${PROJECT_CMAKE_OPTS}" PROJECT_CMAKE_OPTS="-DPROJECT_BUILD_SHARED_LIBS=${PROJECT_BUILD_SHARED_LIBS} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_CMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE} ${PROJECT_CMAKE_OPTS}" PROJECT_CMAKE_OPTS="-DPROJECT_CMAKE_BUILD_TYPE=${PROJECT_CMAKE_BUILD_TYPE} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR} ${PROJECT_CMAKE_OPTS}" PROJECT_CMAKE_OPTS="-DPROJECT_DIST_DIR=${PROJECT_DIST_DIR} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_ENABLE_V2_ERRORS=${PROJECT_ENABLE_V2_ERRORS} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES} ${PROJECT_CMAKE_OPTS}" PROJECT_CMAKE_OPTS="-DPROJECT_ENABLE_WIN32_LONG_PATH_NAMES=${PROJECT_ENABLE_WIN32_LONG_PATH_NAMES} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_EXTERNAL_BUILD_ROOT=${PROJECT_EXTERNAL_BUILD_ROOT} ${PROJECT_CMAKE_OPTS}" PROJECT_CMAKE_OPTS="-DPROJECT_EXTERNAL_BUILD_ROOT=${PROJECT_EXTERNAL_BUILD_ROOT} ${PROJECT_CMAKE_OPTS}"
PROJECT_CMAKE_OPTS="-DPROJECT_GIT_REV=${PROJECT_GIT_REV} ${PROJECT_CMAKE_OPTS}" PROJECT_CMAKE_OPTS="-DPROJECT_GIT_REV=${PROJECT_GIT_REV} ${PROJECT_CMAKE_OPTS}"
@ -307,7 +305,6 @@ export PROJECT_COPYRIGHT
export PROJECT_DESC export PROJECT_DESC
export PROJECT_DIST_DIR export PROJECT_DIST_DIR
export PROJECT_ENABLE_WIN32_LONG_PATH_NAMES export PROJECT_ENABLE_WIN32_LONG_PATH_NAMES
export PROJECT_ENABLE_V2_ERRORS
export PROJECT_FILE_PART export PROJECT_FILE_PART
export PROJECT_GIT_REV export PROJECT_GIT_REV
export PROJECT_IS_ALPINE export PROJECT_IS_ALPINE
@ -358,7 +355,6 @@ echo " Company name: ${PROJECT_COMPANY_NAME}"
echo " Copyright: ${PROJECT_COPYRIGHT}" echo " Copyright: ${PROJECT_COPYRIGHT}"
echo " Description: ${PROJECT_DESC}" echo " Description: ${PROJECT_DESC}"
echo " Dist dir: ${PROJECT_DIST_DIR}" echo " Dist dir: ${PROJECT_DIST_DIR}"
echo " Enable v2 errors: ${PROJECT_ENABLE_V2_ERRORS}"
echo " External build root: ${PROJECT_EXTERNAL_BUILD_ROOT}" echo " External build root: ${PROJECT_EXTERNAL_BUILD_ROOT}"
echo " File part: ${PROJECT_FILE_PART}" echo " File part: ${PROJECT_FILE_PART}"
echo " Is ARM64: ${PROJECT_IS_ARM64}" echo " Is ARM64: ${PROJECT_IS_ARM64}"

View File

@ -25,16 +25,12 @@
#include "utils/config.hpp" #include "utils/config.hpp"
namespace repertory::utils::error { namespace repertory::utils::error {
[[nodiscard]] auto create_error_message(std::vector<std::string_view> items) [[nodiscard]] auto
-> std::string; create_error_message(std::vector<std::string_view> items) -> std::string;
[[nodiscard]] auto create_error_message(std::string_view function_name, [[nodiscard]] auto
std::vector<std::string_view> items) create_exception(std::string_view function_name,
-> std::string; std::vector<std::string_view> items) -> std::runtime_error;
[[nodiscard]] auto create_exception(std::string_view function_name,
std::vector<std::string_view> items)
-> std::runtime_error;
struct i_exception_handler { struct i_exception_handler {
virtual ~i_exception_handler() {} virtual ~i_exception_handler() {}
@ -44,11 +40,6 @@ struct i_exception_handler {
auto operator=(const i_exception_handler &) noexcept = delete; auto operator=(const i_exception_handler &) noexcept = delete;
auto operator=(i_exception_handler &&) noexcept = delete; auto operator=(i_exception_handler &&) noexcept = delete;
#if defined(PROJECT_ENABLE_V2_ERRORS)
virtual void handle_debug(std::string_view function_name,
std::string_view msg) const = 0;
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
virtual void handle_error(std::string_view function_name, virtual void handle_error(std::string_view function_name,
std::string_view msg) const = 0; std::string_view msg) const = 0;
@ -57,107 +48,56 @@ struct i_exception_handler {
virtual void handle_exception(std::string_view function_name, virtual void handle_exception(std::string_view function_name,
const std::exception &ex) const = 0; const std::exception &ex) const = 0;
#if defined(PROJECT_ENABLE_V2_ERRORS)
virtual void handle_info(std::string_view function_name,
std::string_view msg) const = 0;
virtual void handle_trace(std::string_view function_name,
std::string_view msg) const = 0;
virtual void handle_warn(std::string_view function_name,
std::string_view msg) const = 0;
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
protected: protected:
i_exception_handler() = default; i_exception_handler() = default;
}; };
struct iostream_exception_handler final : public i_exception_handler { struct iostream_exception_handler final : i_exception_handler {
#if defined(PROJECT_ENABLE_V2_ERRORS)
void handle_debug(std::string_view function_name,
std::string_view msg) const override;
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
void handle_error(std::string_view function_name, void handle_error(std::string_view function_name,
std::string_view msg) const override; std::string_view msg) const override {
std::cerr << create_error_message({
function_name,
msg,
})
<< std::endl;
}
void handle_exception(std::string_view function_name) const override; void handle_exception(std::string_view function_name) const override {
std::cerr << create_error_message({
function_name,
"exception",
"unknown",
})
<< std::endl;
}
void handle_exception(std::string_view function_name, void handle_exception(std::string_view function_name,
const std::exception &ex) const override; const std::exception &ex) const override {
std::cerr << create_error_message({
#if defined(PROJECT_ENABLE_V2_ERRORS) function_name,
void handle_info(std::string_view function_name, "exception",
std::string_view msg) const override; (ex.what() == nullptr ? "unknown" : ex.what()),
})
void handle_trace(std::string_view function_name, << std::endl;
std::string_view msg) const override; }
void handle_warn(std::string_view function_name,
std::string_view msg) const override;
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
}; };
#if defined(PROJECT_ENABLE_SPDLOG) && defined(PROJECT_ENABLE_V2_ERRORS)
struct spdlog_exception_handler final : public i_exception_handler {
void handle_debug(std::string_view function_name,
std::string_view msg) const override;
void handle_error(std::string_view function_name,
std::string_view msg) const override;
void handle_exception(std::string_view function_name) const override;
void handle_exception(std::string_view function_name,
const std::exception &ex) const override;
void handle_info(std::string_view function_name,
std::string_view msg) const override;
void handle_trace(std::string_view function_name,
std::string_view msg) const override;
void handle_warn(std::string_view function_name,
std::string_view msg) const override;
private:
iostream_exception_handler fallback{};
};
#endif // defined(PROJECT_ENABLE_SPDLOG) && defined(PROJECT_ENABLE_V2_ERRORS)
#if defined(PROJECT_ENABLE_SPDLOG) && defined(PROJECT_ENABLE_V2_ERRORS)
inline const spdlog_exception_handler default_exception_handler{};
#else // !defined(PROJECT_ENABLE_SPDLOG) || !defined(PROJECT_ENABLE_V2_ERRORS)
inline const iostream_exception_handler default_exception_handler{}; inline const iostream_exception_handler default_exception_handler{};
#endif // defined(PROJECT_ENABLE_SPDLOG) && defined(PROJECT_ENABLE_V2_ERRORS)
#if defined(PROJECT_ENABLE_TESTING)
extern std::atomic<const i_exception_handler *> exception_handler; extern std::atomic<const i_exception_handler *> exception_handler;
[[nodiscard]] inline auto get_exception_handler() #if defined(PROJECT_ENABLE_TESTING)
-> const i_exception_handler * { [[nodiscard]] inline auto
get_exception_handler() -> const i_exception_handler * {
return exception_handler; return exception_handler;
} }
#endif // defined(PROJECT_ENABLE_TESTING) #endif // defined(PROJECT_ENABLE_TESTING)
#if defined(PROJECT_ENABLE_V2_ERRORS)
void handle_debug(std::string_view function_name, std::string_view msg);
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
void handle_error(std::string_view function_name, std::string_view msg); void handle_error(std::string_view function_name, std::string_view msg);
void handle_exception(std::string_view function_name); void handle_exception(std::string_view function_name);
void handle_exception(std::string_view function_name, const std::exception &ex); void handle_exception(std::string_view function_name, const std::exception &ex);
#if defined(PROJECT_ENABLE_V2_ERRORS)
void handle_info(std::string_view function_name, std::string_view msg);
void handle_trace(std::string_view function_name, std::string_view msg);
void handle_warn(std::string_view function_name, std::string_view msg);
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
void set_exception_handler(const i_exception_handler *handler); void set_exception_handler(const i_exception_handler *handler);
} // namespace repertory::utils::error } // namespace repertory::utils::error

View File

@ -22,6 +22,9 @@
#include "utils/error.hpp" #include "utils/error.hpp"
namespace repertory::utils::error { namespace repertory::utils::error {
std::atomic<const i_exception_handler *> exception_handler{
&default_exception_handler};
auto create_error_message(std::vector<std::string_view> items) -> std::string { auto create_error_message(std::vector<std::string_view> items) -> std::string {
std::stringstream stream{}; std::stringstream stream{};
for (std::size_t idx = 0U; idx < items.size(); ++idx) { for (std::size_t idx = 0U; idx < items.size(); ++idx) {
@ -35,30 +38,13 @@ auto create_error_message(std::vector<std::string_view> items) -> std::string {
return stream.str(); return stream.str();
} }
auto create_error_message(std::string_view function_name,
std::vector<std::string_view> items) -> std::string {
items.insert(items.begin(), function_name);
return create_error_message(items);
}
auto create_exception(std::string_view function_name, auto create_exception(std::string_view function_name,
std::vector<std::string_view> items) std::vector<std::string_view> items)
-> std::runtime_error { -> std::runtime_error {
return std::runtime_error(create_error_message(function_name, items)); items.insert(items.begin(), function_name);
return std::runtime_error(create_error_message(items));
} }
#if defined(PROJECT_ENABLE_V2_ERRORS)
void handle_debug(std::string_view function_name, std::string_view msg) {
const i_exception_handler *handler{exception_handler};
if (handler != nullptr) {
handler->handle_debug(function_name, msg);
return;
}
default_exception_handler.handle_debug(function_name, msg);
}
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
void handle_error(std::string_view function_name, std::string_view msg) { void handle_error(std::string_view function_name, std::string_view msg) {
const i_exception_handler *handler{exception_handler}; const i_exception_handler *handler{exception_handler};
if (handler != nullptr) { if (handler != nullptr) {
@ -90,38 +76,6 @@ void handle_exception(std::string_view function_name,
default_exception_handler.handle_exception(function_name, ex); default_exception_handler.handle_exception(function_name, ex);
} }
#if defined(PROJECT_ENABLE_V2_ERRORS)
void handle_info(std::string_view function_name, std::string_view msg) {
const i_exception_handler *handler{exception_handler};
if (handler != nullptr) {
handler->handle_info(function_name, msg);
return;
}
default_exception_handler.handle_info(function_name, msg);
}
void handle_trace(std::string_view function_name, std::string_view msg) {
const i_exception_handler *handler{exception_handler};
if (handler != nullptr) {
handler->handle_trace(function_name, msg);
return;
}
default_exception_handler.handle_trace(function_name, msg);
}
void handle_warn(std::string_view function_name, std::string_view msg) {
const i_exception_handler *handler{exception_handler};
if (handler != nullptr) {
handler->handle_warn(function_name, msg);
return;
}
default_exception_handler.handle_warn(function_name, msg);
}
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
void set_exception_handler(const i_exception_handler *handler) { void set_exception_handler(const i_exception_handler *handler) {
exception_handler = handler; exception_handler = handler;
} }

View File

@ -1,241 +0,0 @@
/*
Copyright <2018-2025> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/config.hpp"
#include "utils/error.hpp"
namespace repertory::utils::error {
std::atomic<const i_exception_handler *> exception_handler{
&default_exception_handler};
#if defined(PROJECT_ENABLE_V2_ERRORS)
void iostream_exception_handler::handle_debug(std::string_view function_name,
std::string_view msg) const {
std::cout << create_error_message({
"debug",
function_name,
msg,
})
<< std::endl;
}
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
void iostream_exception_handler::handle_error(std::string_view function_name,
std::string_view msg) const {
std::cerr << create_error_message({
"error",
function_name,
msg,
})
<< std::endl;
}
void iostream_exception_handler::handle_exception(
std::string_view function_name) const {
std::cerr << create_error_message({
"error",
function_name,
"exception",
"unknown",
})
<< std::endl;
}
void iostream_exception_handler::handle_exception(
std::string_view function_name, const std::exception &ex) const {
std::cerr << create_error_message({
"error",
function_name,
"exception",
(ex.what() == nullptr ? "unknown" : ex.what()),
})
<< std::endl;
}
#if defined(PROJECT_ENABLE_V2_ERRORS)
void iostream_exception_handler::handle_info(std::string_view function_name,
std::string_view msg) const {
std::cout << create_error_message({
"info",
function_name,
msg,
})
<< std::endl;
}
void iostream_exception_handler::handle_trace(std::string_view function_name,
std::string_view msg) const {
std::cout << create_error_message({
"trace",
function_name,
msg,
})
<< std::endl;
}
void iostream_exception_handler::handle_warn(std::string_view function_name,
std::string_view msg) const {
std::cout << create_error_message({
"warn",
function_name,
msg,
})
<< std::endl;
}
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
#if defined(PROJECT_ENABLE_SPDLOG) && defined(PROJECT_ENABLE_V2_ERRORS)
void spdlog_exception_handler::handle_debug(std::string_view function_name,
std::string_view msg) const {
auto console = spdlog::get("console");
if (console) {
console->debug(utils::error::create_error_message(function_name, {msg}));
} else {
fallback.handle_debug(function_name, msg);
}
auto file = spdlog::get("file");
if (not file) {
return;
}
file->debug(utils::error::create_error_message(function_name, {msg}));
}
void spdlog_exception_handler::handle_error(std::string_view function_name,
std::string_view msg) const {
auto console = spdlog::get("console");
if (console) {
console->error(utils::error::create_error_message(function_name, {msg}));
} else {
fallback.handle_error(function_name, msg);
}
auto file = spdlog::get("file");
if (not file) {
return;
}
file->error(utils::error::create_error_message(function_name, {msg}));
}
void spdlog_exception_handler::handle_exception(
std::string_view function_name) const {
auto console = spdlog::get("console");
if (console) {
console->error(utils::error::create_error_message(function_name,
{
"exception",
"unknown exception",
}));
} else {
fallback.handle_exception(function_name);
}
auto file = spdlog::get("file");
if (not file) {
return;
}
file->error(
utils::error::create_error_message(function_name, {
"exception",
"unknown exception",
}));
}
void spdlog_exception_handler::handle_exception(
std::string_view function_name, const std::exception &ex) const {
auto console = spdlog::get("console");
if (console) {
console->error(utils::error::create_error_message(
function_name, {
"exception",
(ex.what() == nullptr ? "unknown" : ex.what()),
}));
} else {
fallback.handle_exception(function_name, ex);
}
auto file = spdlog::get("file");
if (not file) {
return;
}
file->error(utils::error::create_error_message(
function_name, {
"exception",
(ex.what() == nullptr ? "unknown" : ex.what()),
}));
}
void spdlog_exception_handler::handle_info(std::string_view function_name,
std::string_view msg) const {
auto console = spdlog::get("console");
if (console) {
console->info(utils::error::create_error_message(function_name, {msg}));
} else {
fallback.handle_info(function_name, msg);
}
auto file = spdlog::get("file");
if (not file) {
return;
}
file->info(utils::error::create_error_message(function_name, {msg}));
}
void spdlog_exception_handler::handle_trace(std::string_view function_name,
std::string_view msg) const {
auto console = spdlog::get("console");
if (console) {
console->trace(utils::error::create_error_message(function_name, {msg}));
} else {
fallback.handle_trace(function_name, msg);
}
auto file = spdlog::get("file");
if (not file) {
return;
}
file->trace(utils::error::create_error_message(function_name, {msg}));
}
void spdlog_exception_handler::handle_warn(std::string_view function_name,
std::string_view msg) const {
auto console = spdlog::get("console");
if (console) {
console->warn(utils::error::create_error_message(function_name, {msg}));
} else {
fallback.handle_warn(function_name, msg);
}
auto file = spdlog::get("file");
if (not file) {
return;
}
file->warn(utils::error::create_error_message(function_name, {msg}));
}
#endif // defined(PROJECT_ENABLE_SPDLOG) && defined(PROJECT_ENABLE_V2_ERRORS)
} // namespace repertory::utils::error

View File

@ -41,16 +41,8 @@ auto change_to_process_directory() -> bool {
::GetModuleFileNameA(nullptr, file_name.data(), ::GetModuleFileNameA(nullptr, file_name.data(),
static_cast<DWORD>(file_name.size() - 1U)); static_cast<DWORD>(file_name.size() - 1U));
auto path = utils::path::get_parent_path(file_name.c_str()); auto path = utils::path::strip_to_file_name(file_name.c_str());
auto res = ::SetCurrentDirectoryA(path.c_str()) != 0; ::SetCurrentDirectoryA(path.c_str());
if (not res) {
throw utils::error::create_exception(
function_name, {
"failed to set current directory",
std::to_string(utils::get_last_error_code()),
path,
});
}
#else // !defined(_WIN32) #else // !defined(_WIN32)
std::string path; std::string path;
path.resize(PATH_MAX + 1); path.resize(PATH_MAX + 1);

View File

@ -29,28 +29,15 @@ TEST(utils_error, check_default_exception_handler) {
EXPECT_TRUE(utils::error::get_exception_handler() != nullptr); EXPECT_TRUE(utils::error::get_exception_handler() != nullptr);
if (&utils::error::default_exception_handler == if (&utils::error::default_exception_handler ==
utils::error::get_exception_handler()) { utils::error::get_exception_handler()) {
#if defined(PROJECT_ENABLE_SPDLOG) && defined(PROJECT_ENABLE_V2_ERRORS)
auto default_handler_is_spdlog =
is_decay_equ<decltype(utils::error::default_exception_handler),
utils::error::spdlog_exception_handler>;
EXPECT_TRUE(default_handler_is_spdlog);
#else // !defined(PROJECT_ENABLE_SPDLOG) || !defined(PROJECT_ENABLE_V2_ERRORS)
auto default_handler_is_iostream = auto default_handler_is_iostream =
is_decay_equ<decltype(utils::error::default_exception_handler), is_decay_equ<decltype(utils::error::default_exception_handler),
utils::error::iostream_exception_handler>; utils::error::iostream_exception_handler>;
EXPECT_TRUE(default_handler_is_iostream); EXPECT_TRUE(default_handler_is_iostream);
#endif
} }
} }
TEST(utils_error, can_override_exception_handler) { TEST(utils_error, can_override_exception_handler) {
struct my_exc_handler final : public utils::error::i_exception_handler { struct my_exc_handler final : public utils::error::i_exception_handler {
#if defined(PROJECT_ENABLE_V2_ERRORS)
MOCK_METHOD(void, handle_debug,
(std::string_view function_name, std::string_view msg),
(const, override));
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
MOCK_METHOD(void, handle_error, MOCK_METHOD(void, handle_error,
(std::string_view function_name, std::string_view msg), (std::string_view function_name, std::string_view msg),
(const, override)); (const, override));
@ -61,30 +48,11 @@ TEST(utils_error, can_override_exception_handler) {
MOCK_METHOD(void, handle_exception, MOCK_METHOD(void, handle_exception,
(std::string_view function_name, const std::exception &ex), (std::string_view function_name, const std::exception &ex),
(const, override)); (const, override));
#if defined(PROJECT_ENABLE_V2_ERRORS)
MOCK_METHOD(void, handle_info,
(std::string_view function_name, std::string_view msg),
(const, override));
MOCK_METHOD(void, handle_trace,
(std::string_view function_name, std::string_view msg),
(const, override));
MOCK_METHOD(void, handle_warn,
(std::string_view function_name, std::string_view msg),
(const, override));
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
}; };
my_exc_handler handler{}; my_exc_handler handler{};
utils::error::set_exception_handler(&handler); utils::error::set_exception_handler(&handler);
#if defined(PROJECT_ENABLE_V2_ERRORS)
EXPECT_CALL(handler, handle_debug("test_func", "debug")).WillOnce(Return());
utils::error::handle_debug("test_func", "debug");
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
EXPECT_CALL(handler, handle_error("test_func", "error")).WillOnce(Return()); EXPECT_CALL(handler, handle_error("test_func", "error")).WillOnce(Return());
utils::error::handle_error("test_func", "error"); utils::error::handle_error("test_func", "error");
@ -100,17 +68,6 @@ TEST(utils_error, can_override_exception_handler) {
}); });
utils::error::handle_exception("test_func_ex", ex); utils::error::handle_exception("test_func_ex", ex);
#if defined(PROJECT_ENABLE_V2_ERRORS)
EXPECT_CALL(handler, handle_info("test_func", "info")).WillOnce(Return());
utils::error::handle_info("test_func", "info");
EXPECT_CALL(handler, handle_trace("test_func", "trace")).WillOnce(Return());
utils::error::handle_trace("test_func", "trace");
EXPECT_CALL(handler, handle_warn("test_func", "warn")).WillOnce(Return());
utils::error::handle_warn("test_func", "warn");
#endif // defined(PROJECT_ENABLE_V2_ERRORS)
utils::error::set_exception_handler(&utils::error::default_exception_handler); utils::error::set_exception_handler(&utils::error::default_exception_handler);
} }
} // namespace repertory } // namespace repertory