mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-10-28 10:48:49 -04:00
added whisparr v3 to e2e arr stack
This commit is contained in:
1 parent
0e2de577d8
commit
f84c149fd9
11 files changed
+117
-23
No files matched your search
+2
-2
@@ -13,7 +13,7 @@ APP_SERVICES = app nginx
|
||||
|
||||
CORE_STACK = keycloak $(WIREMOCKS)
|
||||
CLIENTS_STACK = $(CORE_STACK) tracker qbittorrent transmission deluge utorrent rutorrent sabnews sabnzbd
|
||||
ARR_STACK = $(CORE_STACK) wiremock-indexer tracker qbittorrent sonarr radarr
|
||||
ARR_STACK = $(CORE_STACK) wiremock-indexer tracker qbittorrent sonarr radarr whisparr
|
||||
LAZYLIBRARIAN_STACK = $(CORE_STACK) wiremock-indexer tracker qbittorrent sabnews sabnzbd lazylibrarian
|
||||
|
||||
setup:
|
||||
@@ -61,7 +61,7 @@ up-app:
|
||||
$(COMPOSE) up -d $(WAIT) $(APP_SERVICES)
|
||||
|
||||
# Rebuilds e2e/arr-seed from scratch.
|
||||
# Needs internet: Sonarr reads Skyhook and Radarr reads TMDB.
|
||||
# Needs internet: each arr reads its metadata provider.
|
||||
seed-arr:
|
||||
bash ./scripts/seed-arr.sh
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<Config>
|
||||
<BindAddress>*</BindAddress>
|
||||
<Port>6970</Port>
|
||||
<EnableSsl>False</EnableSsl>
|
||||
<LaunchBrowser>False</LaunchBrowser>
|
||||
<ApiKey>0000000000000000000000000000e2e6</ApiKey>
|
||||
<AuthenticationMethod>External</AuthenticationMethod>
|
||||
<AuthenticationRequired>DisabledForLocalAddresses</AuthenticationRequired>
|
||||
<Branch>eros</Branch>
|
||||
<LogLevel>info</LogLevel>
|
||||
<UrlBase></UrlBase>
|
||||
<InstanceName>Whisparr</InstanceName>
|
||||
<UpdateMechanism>Docker</UpdateMechanism>
|
||||
<AnalyticsEnabled>False</AnalyticsEnabled>
|
||||
<WhisparrMetadata>https://api.whisparr.com/v4/{route}</WhisparrMetadata>
|
||||
<SslPort>9898</SslPort>
|
||||
<SslCertPath></SslCertPath>
|
||||
<SslCertPassword></SslCertPassword>
|
||||
</Config>
|
||||
Binary file not shown.
@@ -213,7 +213,7 @@ services:
|
||||
retries: 12
|
||||
start_period: 30s
|
||||
|
||||
# Real Sonarr and Radarr, restored from e2e/arr-seed by setup-test-data.sh.
|
||||
# Real Sonarr, Radarr and Whisparr, restored from e2e/arr-seed by setup-test-data.sh.
|
||||
# Every run starts with the same library, API key, indexer and download client.
|
||||
# Regenerate the seed with `make seed-arr`.
|
||||
# The tags are pinned: a seed database is only valid for the version that wrote it.
|
||||
@@ -253,6 +253,25 @@ services:
|
||||
retries: 12
|
||||
start_period: 30s
|
||||
|
||||
# Listens on 6970 from the seeded config.xml, since the tracker holds 6969.
|
||||
whisparr:
|
||||
image: ghcr.io/hotio/whisparr:v3-3.1.0.2116
|
||||
network_mode: host
|
||||
environment:
|
||||
PUID: "${E2E_PUID:-1000}"
|
||||
PGID: "${E2E_PGID:-1000}"
|
||||
TZ: "UTC"
|
||||
volumes:
|
||||
- ./test-data/whisparr-config:/config
|
||||
- ./test-data/whisparr-movies:/movies
|
||||
- ./test-data/downloads/qbittorrent:/downloads
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -fs -o /dev/null http://localhost:6970/ping || exit 1"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 12
|
||||
start_period: 30s
|
||||
|
||||
# Real LazyLibrarian, restored from e2e/lazylibrarian-seed by setup-test-data.sh.
|
||||
# LazyLibrarian publishes no versions, so the tag names the upstream commit.
|
||||
# The seed database is only valid for the commit that wrote it.
|
||||
|
||||
+37
-10
@@ -6,8 +6,8 @@
|
||||
# Snapshots /config into e2e/arr-seed, which the e2e run restores.
|
||||
# CI therefore needs no network and every run sees the same library.
|
||||
#
|
||||
# Needs internet: Sonarr reads Skyhook and Radarr reads TMDB.
|
||||
# Stops the sonarr and radarr containers.
|
||||
# Needs internet: each arr reads its metadata provider.
|
||||
# Stops the sonarr, radarr and whisparr containers.
|
||||
#
|
||||
# Re-run it when the pinned image tags change, or when the library has to change.
|
||||
#
|
||||
@@ -20,8 +20,10 @@ COMPOSE="docker compose -f $HERE/docker-compose.e2e.yml"
|
||||
|
||||
SONARR_URL="http://localhost:8989"
|
||||
RADARR_URL="http://localhost:7878"
|
||||
WHISPARR_URL="http://localhost:6970"
|
||||
SONARR_API_KEY="0000000000000000000000000000e2e1"
|
||||
RADARR_API_KEY="0000000000000000000000000000e2e2"
|
||||
WHISPARR_API_KEY="0000000000000000000000000000e2e6"
|
||||
|
||||
# The mock Torznab indexer, and qBittorrent, both on the host network.
|
||||
INDEXER_URL="http://127.0.0.1:9500"
|
||||
@@ -39,6 +41,8 @@ RADARR_TMDB_ID=911430
|
||||
# The Wild Robot, added second and left unmonitored.
|
||||
# The specs that need two candidates monitor it themselves and restore it after.
|
||||
RADARR_SECOND_TMDB_ID=1184918
|
||||
# Package Holiday (2004): a plain title, since the seed database is public.
|
||||
WHISPARR_TMDB_ID=1253309
|
||||
|
||||
log() {
|
||||
echo "[seed-arr] $*"
|
||||
@@ -252,9 +256,25 @@ seed_radarr() {
|
||||
wait_for_items "$RADARR_URL" "$RADARR_API_KEY" '/api/v3/movie' 'radarr movies'
|
||||
}
|
||||
|
||||
seed_whisparr() {
|
||||
log "configuring whisparr"
|
||||
arr_post "$WHISPARR_URL" "$WHISPARR_API_KEY" '/api/v3/rootfolder' '{"path":"/movies"}' > /dev/null
|
||||
add_indexer "$WHISPARR_URL" "$WHISPARR_API_KEY" '[6000]'
|
||||
add_download_client "$WHISPARR_URL" "$WHISPARR_API_KEY" 'movieCategory' 'whisparr'
|
||||
|
||||
log "adding the whisparr movie"
|
||||
local movie
|
||||
movie=$(arr_get "$WHISPARR_URL" "$WHISPARR_API_KEY" "/api/v3/movie/lookup?term=tmdb%3A$WHISPARR_TMDB_ID" \
|
||||
| merge_add_options '/movies' '{"searchForMovie":false}')
|
||||
arr_post "$WHISPARR_URL" "$WHISPARR_API_KEY" '/api/v3/movie' "$movie" > /dev/null
|
||||
|
||||
wait_for_items "$WHISPARR_URL" "$WHISPARR_API_KEY" '/api/v3/movie' 'whisparr movies'
|
||||
}
|
||||
|
||||
# Keeps the database and config.xml, drops everything the arr rebuilds on start.
|
||||
# Whisparr v3 names its database whisparr3.db.
|
||||
snapshot() {
|
||||
local arr="$1"
|
||||
local arr="$1" db="${2:-$1}"
|
||||
local src="$TEST_DATA/$arr-config"
|
||||
local dest="$ARR_SEED/$arr"
|
||||
|
||||
@@ -265,15 +285,15 @@ snapshot() {
|
||||
|
||||
# The arr leaves committed rows in the write-ahead log.
|
||||
# The log comes along and is folded into the database before it is dropped.
|
||||
cp "$src/$arr.db" "$dest/$arr.db"
|
||||
cp "$src/$db.db" "$dest/$db.db"
|
||||
for suffix in wal shm; do
|
||||
if [[ -f "$src/$arr.db-$suffix" ]]; then
|
||||
cp "$src/$arr.db-$suffix" "$dest/$arr.db-$suffix"
|
||||
if [[ -f "$src/$db.db-$suffix" ]]; then
|
||||
cp "$src/$db.db-$suffix" "$dest/$db.db-$suffix"
|
||||
fi
|
||||
done
|
||||
|
||||
sqlite3 "$dest/$arr.db" 'PRAGMA journal_mode=DELETE; VACUUM;' > /dev/null
|
||||
rm -f "$dest/$arr.db-wal" "$dest/$arr.db-shm"
|
||||
sqlite3 "$dest/$db.db" 'PRAGMA journal_mode=DELETE; VACUUM;' > /dev/null
|
||||
rm -f "$dest/$db.db-wal" "$dest/$db.db-shm"
|
||||
}
|
||||
|
||||
main() {
|
||||
@@ -281,23 +301,30 @@ main() {
|
||||
|
||||
write_config_xml "$TEST_DATA/sonarr-config" 8989 "$SONARR_API_KEY" 'Sonarr'
|
||||
write_config_xml "$TEST_DATA/radarr-config" 7878 "$RADARR_API_KEY" 'Radarr'
|
||||
write_config_xml "$TEST_DATA/whisparr-config" 6970 "$WHISPARR_API_KEY" 'Whisparr'
|
||||
|
||||
# An arr tests the indexer and the download client before it saves them.
|
||||
# Both have to answer during seeding.
|
||||
log "starting the arrs"
|
||||
$COMPOSE up -d --force-recreate wiremock-indexer qbittorrent sonarr radarr
|
||||
$COMPOSE up -d --force-recreate wiremock-indexer qbittorrent sonarr radarr whisparr
|
||||
|
||||
wait_for_arr "$SONARR_URL" 'sonarr'
|
||||
wait_for_arr "$RADARR_URL" 'radarr'
|
||||
wait_for_arr "$WHISPARR_URL" 'whisparr'
|
||||
|
||||
seed_sonarr
|
||||
seed_radarr
|
||||
seed_whisparr
|
||||
|
||||
log "stopping the arrs"
|
||||
$COMPOSE stop wiremock-indexer qbittorrent sonarr radarr
|
||||
$COMPOSE stop wiremock-indexer qbittorrent sonarr radarr whisparr
|
||||
|
||||
snapshot sonarr
|
||||
snapshot radarr
|
||||
snapshot whisparr whisparr3
|
||||
|
||||
# The seed is public, so it keeps the title and drops the synopsis, posters and cast.
|
||||
sqlite3 "$ARR_SEED/whisparr/whisparr3.db" "UPDATE MovieMetadata SET Overview = '', Images = '[]', Credits = '[]'; VACUUM;"
|
||||
|
||||
log "seed written to $ARR_SEED"
|
||||
}
|
||||
|
||||
@@ -16,12 +16,13 @@ ARR_SEED="$HERE/arr-seed"
|
||||
rm -rf "$TEST_DATA/torznab-src"
|
||||
|
||||
# Media an arr imports during a run, wiped so its library always starts empty.
|
||||
rm -rf "$TEST_DATA/sonarr-tv" "$TEST_DATA/radarr-movies" "$TEST_DATA/lazylibrarian-books"
|
||||
rm -rf "$TEST_DATA/sonarr-tv" "$TEST_DATA/radarr-movies" "$TEST_DATA/whisparr-movies" "$TEST_DATA/lazylibrarian-books"
|
||||
|
||||
mkdir -p \
|
||||
"$TEST_DATA/torznab-src" \
|
||||
"$TEST_DATA/sonarr-tv" \
|
||||
"$TEST_DATA/radarr-movies" \
|
||||
"$TEST_DATA/whisparr-movies" \
|
||||
"$TEST_DATA/lazylibrarian-books" \
|
||||
"$TEST_DATA/downloads/qbittorrent" \
|
||||
"$TEST_DATA/downloads/transmission" \
|
||||
@@ -100,9 +101,9 @@ script = Default
|
||||
priority = 0
|
||||
EOF
|
||||
|
||||
# Restore Sonarr and Radarr from the committed seed.
|
||||
# Restore Sonarr, Radarr and Whisparr from the committed seed.
|
||||
# The arrs write to /config on every start, so the run gets a throwaway copy.
|
||||
for arr in sonarr radarr; do
|
||||
for arr in sonarr radarr whisparr; do
|
||||
if [[ -d "$ARR_SEED/$arr" ]]; then
|
||||
rm -rf "$TEST_DATA/$arr-config"
|
||||
cp -R "$ARR_SEED/$arr" "$TEST_DATA/$arr-config"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { TEST_CONFIG } from './test-config';
|
||||
import { WireMockClient } from './mocks/wiremock-client';
|
||||
|
||||
/**
|
||||
* Direct access to the real Sonarr and Radarr containers.
|
||||
* Direct access to the real Sonarr, Radarr and Whisparr v3 containers.
|
||||
*
|
||||
* The specs drive Cleanuparr through its own API, like every other spec.
|
||||
* This is the other side of the contract: what the arr itself ended up with.
|
||||
@@ -141,5 +141,11 @@ export const liveRadarr = new LiveArr(
|
||||
'includeUnknownMovieItems=true&includeMovie=true',
|
||||
);
|
||||
|
||||
export const liveWhisparr = new LiveArr(
|
||||
TEST_CONFIG.liveArr.whisparrUrl,
|
||||
TEST_CONFIG.liveArr.whisparrApiKey,
|
||||
'includeUnknownMovieItems=true&includeMovie=true',
|
||||
);
|
||||
|
||||
/** The fake Torznab indexer, kept out of MockServers: other suites lack its container. */
|
||||
export const indexerMock = new WireMockClient(TEST_CONFIG.mocks.indexerAdminUrl);
|
||||
@@ -16,6 +16,7 @@ export type TorznabSearchMode = 'tvsearch' | 'movie' | 'search';
|
||||
/** Torznab category. The seeded arrs are configured for the parent categories. */
|
||||
export const TORZNAB_TV_CATEGORY = 5040;
|
||||
export const TORZNAB_MOVIE_CATEGORY = 2040;
|
||||
export const TORZNAB_XXX_CATEGORY = 6040;
|
||||
|
||||
/**
|
||||
* The advertised release size.
|
||||
|
||||
@@ -6,9 +6,9 @@ import { buildSingleFileTorrent } from './torrent-fixtures';
|
||||
import type { CleanuparrApi } from './api';
|
||||
import { buildDownloadClientPayload } from './api/download-client';
|
||||
import type { ArrType } from './api/arr';
|
||||
import { LiveArr, indexerMock, liveRadarr, liveSonarr } from './live-arr';
|
||||
import { LiveArr, indexerMock, liveRadarr, liveSonarr, liveWhisparr } from './live-arr';
|
||||
import { QBittorrentDriver } from './torrent-clients/qbittorrent';
|
||||
import { TORZNAB_MOVIE_CATEGORY, TORZNAB_TV_CATEGORY } from './mocks/torznab-stubs';
|
||||
import { TORZNAB_MOVIE_CATEGORY, TORZNAB_TV_CATEGORY, TORZNAB_XXX_CATEGORY } from './mocks/torznab-stubs';
|
||||
import { mkdirShared, writeFileShared } from './shared-volume';
|
||||
|
||||
/**
|
||||
@@ -97,6 +97,21 @@ export const RADARR: SeededArr = {
|
||||
downloadCategory: 'radarr',
|
||||
};
|
||||
|
||||
export const WHISPARR: SeededArr = {
|
||||
type: 'whisparr',
|
||||
arr: liveWhisparr,
|
||||
url: TEST_CONFIG.liveArr.whisparrUrl,
|
||||
apiKey: TEST_CONFIG.liveArr.whisparrApiKey,
|
||||
version: 3,
|
||||
searchMode: 'movie',
|
||||
category: TORZNAB_XXX_CATEGORY,
|
||||
release: `Package.Holiday.2004.1080p.WEB-DL.x264-E2E${RUN_TAG}`,
|
||||
itemId: 1,
|
||||
itemPath: 'movie',
|
||||
seededTitle: TEST_CONFIG.liveArr.seededWhisparrTitle,
|
||||
downloadCategory: 'whisparr',
|
||||
};
|
||||
|
||||
export const qbittorrent = new QBittorrentDriver();
|
||||
|
||||
/** Outside the qBittorrent save path, so a decoy download never finds its data. */
|
||||
@@ -289,15 +304,15 @@ export async function waitForArrQueue(arr: LiveArr, downloadId: string, timeoutM
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties both arr queues and the download client.
|
||||
* Empties every arr queue and the download client.
|
||||
*
|
||||
* The Seeker skips an item that is already downloading.
|
||||
* The client is purged first, or the arr re-adds the torrent on its next refresh.
|
||||
*/
|
||||
export async function resetDownloads(): Promise<void> {
|
||||
await qbittorrent.clearAllTorrents();
|
||||
await Promise.all([liveSonarr.clearQueue(), liveRadarr.clearQueue()]);
|
||||
await Promise.all([waitForEmptyQueue(liveSonarr), waitForEmptyQueue(liveRadarr)]);
|
||||
await Promise.all([liveSonarr.clearQueue(), liveRadarr.clearQueue(), liveWhisparr.clearQueue()]);
|
||||
await Promise.all([waitForEmptyQueue(liveSonarr), waitForEmptyQueue(liveRadarr), waitForEmptyQueue(liveWhisparr)]);
|
||||
}
|
||||
|
||||
async function waitForEmptyQueue(arr: LiveArr, timeoutMs = 120_000): Promise<void> {
|
||||
|
||||
@@ -26,7 +26,7 @@ export const TEST_CONFIG = {
|
||||
indexerAdminUrl: 'http://localhost:9500/__admin',
|
||||
},
|
||||
|
||||
// The real Sonarr and Radarr containers.
|
||||
// The real Sonarr, Radarr and Whisparr v3 containers.
|
||||
// Their api keys come from the committed seed in e2e/arr-seed.
|
||||
liveArr: {
|
||||
sonarrUrl: 'http://localhost:8989',
|
||||
@@ -35,6 +35,9 @@ export const TEST_CONFIG = {
|
||||
radarrApiKey: '0000000000000000000000000000e2e2',
|
||||
seededSeriesTitle: 'Agatha All Along',
|
||||
seededMovieTitle: 'F1',
|
||||
whisparrUrl: 'http://localhost:6970',
|
||||
whisparrApiKey: '0000000000000000000000000000e2e6',
|
||||
seededWhisparrTitle: 'Package Holiday',
|
||||
},
|
||||
|
||||
// Real qBittorrent container: the API key seeded into
|
||||
|
||||
@@ -17,5 +17,8 @@
|
||||
<category id="5000" name="TV">
|
||||
<subcat id="5040" name="TV/HD" />
|
||||
</category>
|
||||
<category id="6000" name="XXX">
|
||||
<subcat id="6040" name="XXX/x264" />
|
||||
</category>
|
||||
</categories>
|
||||
</caps>
|
||||
Reference in new issue
Block a user