Run hooks on the code base.
This adds trailing lines to files, removes trailing white space in all the other lines and unifies line endings. Additionally it formats the test code with `black`.
|
@ -1,2 +1,2 @@
|
|||
# Migrate code style to Black
|
||||
b6a24debb78b953117a3f637db18942f370a4b85
|
||||
b6a24debb78b953117a3f637db18942f370a4b85
|
||||
|
|
2
.gitattributes
vendored
|
@ -1 +1 @@
|
|||
*.py diff=python
|
||||
*.py diff=python
|
||||
|
|
4
.github/workflows/test.yml
vendored
|
@ -30,8 +30,8 @@ jobs:
|
|||
black --check .
|
||||
# - name: Run PyLint (info only)
|
||||
# run: pylint --rcfile=setup.cfg src --exit-zero
|
||||
|
||||
|
||||
|
||||
|
||||
test:
|
||||
timeout-minutes: 20
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
|
1
.gitignore
vendored
|
@ -21,4 +21,3 @@ src/vorta/i18n/ts/vorta.en.ts
|
|||
src/vorta/i18n/ts/vorta.en_US.ts
|
||||
flatpak/app/
|
||||
flatpak/.flatpak-builder/
|
||||
|
||||
|
|
|
@ -7,4 +7,3 @@ minimum_perc = 80
|
|||
source_file = src/vorta/i18n/ts/vorta.en.ts
|
||||
source_lang = en
|
||||
type = QT
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ diff -up fuse-2.9.2/include/fuse_kernel.h.conflictfix fuse-2.9.2/include/fuse_ke
|
|||
@@ -88,12 +88,16 @@
|
||||
#ifndef _LINUX_FUSE_H
|
||||
#define _LINUX_FUSE_H
|
||||
|
||||
|
||||
-#include <sys/types.h>
|
||||
+#ifdef __linux__
|
||||
+#include <linux/types.h>
|
||||
|
@ -16,6 +16,6 @@ diff -up fuse-2.9.2/include/fuse_kernel.h.conflictfix fuse-2.9.2/include/fuse_ke
|
|||
#define __s32 int32_t
|
||||
#define __u16 uint16_t
|
||||
+#endif
|
||||
|
||||
|
||||
/*
|
||||
* Version negotiation:
|
||||
|
|
|
@ -14,13 +14,12 @@ index 7a18c11..1667db2 100644
|
|||
@@ -392,6 +392,9 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
|
||||
int fd;
|
||||
int res;
|
||||
|
||||
|
||||
+ /* disable in flatpak */
|
||||
+ return -2;
|
||||
+
|
||||
if (!mnt) {
|
||||
fprintf(stderr, "fuse: missing mountpoint parameter\n");
|
||||
return -1;
|
||||
--
|
||||
--
|
||||
2.17.0.rc2
|
||||
|
||||
|
|
|
@ -41,4 +41,4 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,4 +11,4 @@
|
|||
"sha256": "d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,4 +61,4 @@
|
|||
"sha256": "a8975a7df3560c9f1e2b43dc54ebd40fd00a7017392ca5445ce7df409f900fcb"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,4 +11,4 @@
|
|||
"sha256": "f3f5c80c51b632d031f60454accadd84f166453a471bff63093ca674973f2a4e"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,4 +11,4 @@
|
|||
"sha256": "863a85c1c0a5103a12c05a35e59d336e1d665747e531256e061213e2e90f63f3"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,4 +67,4 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,4 +11,4 @@
|
|||
"sha256": "ff64136da01aabba76ae88b050e7197918d8b2139ccbf6144e14d472b9c40445"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,4 +11,4 @@
|
|||
"sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,4 +75,4 @@
|
|||
"sources": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,4 +10,4 @@
|
|||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
|
|
|
@ -81,4 +81,3 @@ app = BUNDLE(coll,
|
|||
'PATH': '/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin'
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="#000000" d="M93.13 257.7C71.25 275.1 53 313.5 38.63 355.1L99 333.1c5.75-2.125 10.62 4.749 6.625 9.499L11 454.7C3.75 486.1 0 510.2 0 510.2s206.6 13.62 266.6-34.12c60-47.87 76.63-150.1 76.63-150.1L256.5 216.7C256.5 216.7 153.1 209.1 93.13 257.7zM633.2 12.34c-10.84-13.91-30.91-16.45-44.91-5.624l-225.7 175.6l-34.99-44.06C322.5 131.9 312.5 133.1 309 140.5L283.8 194.1l86.75 109.2l58.75-12.5c8-1.625 11.38-11.12 6.375-17.5l-33.19-41.79l225.2-175.2C641.6 46.38 644.1 26.27 633.2 12.34z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="#000000" d="M93.13 257.7C71.25 275.1 53 313.5 38.63 355.1L99 333.1c5.75-2.125 10.62 4.749 6.625 9.499L11 454.7C3.75 486.1 0 510.2 0 510.2s206.6 13.62 266.6-34.12c60-47.87 76.63-150.1 76.63-150.1L256.5 216.7C256.5 216.7 153.1 209.1 93.13 257.7zM633.2 12.34c-10.84-13.91-30.91-16.45-44.91-5.624l-225.7 175.6l-34.99-44.06C322.5 131.9 312.5 133.1 309 140.5L283.8 194.1l86.75 109.2l58.75-12.5c8-1.625 11.38-11.12 6.375-17.5l-33.19-41.79l225.2-175.2C641.6 46.38 644.1 26.27 633.2 12.34z"/></svg>
|
||||
|
|
Before Width: | Height: | Size: 731 B After Width: | Height: | Size: 732 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<path fill="#000000" d="M 4 4 L 4 28 L 18 28 L 18 27 L 5 27 L 5 14 L 10 14 L 13 11 L 27 11 L 27 16 L 28 16 L 28 7 L 18 7 L 15 4 L 4 4 z M 23 16 L 18 21 L 18.707031 21.707031 L 22.5 17.914062 L 22.5 28.003906 L 23.5 28.003906 L 23.5 17.914062 L 27.292969 21.707031 L 28 21 L 24 17 L 23 16 z " id="path71" class="ColorScheme-Text" />
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 402 B |
|
@ -1 +1 @@
|
|||
<svg aria-hidden="true" fill="#000000" focusable="false" data-prefix="fas" data-icon="folder" class="svg-inline--fa fa-folder" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M464 96h-192l-64-64h-160C21.5 32 0 53.5 0 80V160h512V144C512 117.5 490.5 96 464 96zM0 432C0 458.5 21.5 480 48 480h416c26.5 0 48-21.5 48-48V192H0V432z"></path></svg>
|
||||
<svg aria-hidden="true" fill="#000000" focusable="false" data-prefix="fas" data-icon="folder" class="svg-inline--fa fa-folder" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M464 96h-192l-64-64h-160C21.5 32 0 53.5 0 80V160h512V144C512 117.5 490.5 96 464 96zM0 432C0 458.5 21.5 480 48 480h416c26.5 0 48-21.5 48-48V192H0V432z"></path></svg>
|
||||
|
|
Before Width: | Height: | Size: 368 B After Width: | Height: | Size: 369 B |
|
@ -1 +1 @@
|
|||
<svg aria-hidden="true" fill="#000000" focusable="false" data-prefix="fas" data-icon="minus" class="svg-inline--fa fa-minus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M400 288h-352c-17.69 0-32-14.32-32-32.01s14.31-31.99 32-31.99h352c17.69 0 32 14.3 32 31.99S417.7 288 400 288z"></path></svg>
|
||||
<svg aria-hidden="true" fill="#000000" focusable="false" data-prefix="fas" data-icon="minus" class="svg-inline--fa fa-minus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M400 288h-352c-17.69 0-32-14.32-32-32.01s14.31-31.99 32-31.99h352c17.69 0 32 14.3 32 31.99S417.7 288 400 288z"></path></svg>
|
||||
|
|
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 327 B |
|
@ -1 +1 @@
|
|||
<svg aria-hidden="true" fill="#00000" focusable="false" data-prefix="fas" data-icon="paste" class="svg-inline--fa fa-paste" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M320 96V80C320 53.49 298.5 32 272 32H215.4C204.3 12.89 183.6 0 160 0S115.7 12.89 104.6 32H48C21.49 32 0 53.49 0 80v320C0 426.5 21.49 448 48 448l144 .0013L192 176C192 131.8 227.8 96 272 96H320zM160 88C146.8 88 136 77.25 136 64S146.8 40 160 40S184 50.75 184 64S173.3 88 160 88zM416 128v96h96L416 128zM384 224L384 128h-112C245.5 128 224 149.5 224 176v288c0 26.51 21.49 48 48 48h192c26.51 0 48-21.49 48-48V256h-95.99C398.4 256 384 241.6 384 224z"></path></svg>
|
||||
<svg aria-hidden="true" fill="#00000" focusable="false" data-prefix="fas" data-icon="paste" class="svg-inline--fa fa-paste" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M320 96V80C320 53.49 298.5 32 272 32H215.4C204.3 12.89 183.6 0 160 0S115.7 12.89 104.6 32H48C21.49 32 0 53.49 0 80v320C0 426.5 21.49 448 48 448l144 .0013L192 176C192 131.8 227.8 96 272 96H320zM160 88C146.8 88 136 77.25 136 64S146.8 40 160 40S184 50.75 184 64S173.3 88 160 88zM416 128v96h96L416 128zM384 224L384 128h-112C245.5 128 224 149.5 224 176v288c0 26.51 21.49 48 48 48h192c26.51 0 48-21.49 48-48V256h-95.99C398.4 256 384 241.6 384 224z"></path></svg>
|
||||
|
|
Before Width: | Height: | Size: 677 B After Width: | Height: | Size: 678 B |
|
@ -1357,11 +1357,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="75"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Aktualizace schématu se nezdařila, vyplňte hlášení chyby s odkazem v panelu Různé s následující chybou:
|
||||
{0}
|
||||
{0}
|
||||
{1}</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -2128,4 +2128,4 @@ Zkuste repozitář odpojit a znovu přidat.</translation>
|
|||
<translation>Je třeba, aby heslo bylo delší než 8 znaků.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1355,11 +1355,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="75"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Schema-Upgrade Fehler, erstelle einen Bugreport auf dem Link um "Misc"-Tab, mit folgendem Fehler:
|
||||
{0}
|
||||
<translation>Schema-Upgrade Fehler, erstelle einen Bugreport auf dem Link um "Misc"-Tab, mit folgendem Fehler:
|
||||
{0}
|
||||
{1}</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -2125,4 +2125,4 @@ Try unlinking and re-adding your repo.</source>
|
|||
<translation>Passwörter müssen länger als 8 Zeichen sein.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1357,8 +1357,8 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="75"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Falla al actualizar esquema, registre un reporte de error con el enlace en la pestaña Varios con el siguiente error:
|
||||
{0}
|
||||
|
@ -2128,4 +2128,4 @@ Intente desvincular y volver a agregar su repositorio.</translation>
|
|||
<translation>Las contraseñas deben ser mayor a 8 caracteres.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1357,11 +1357,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="75"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Skeeman päivitys epäonnistui, lähetä virheraportti Sekalaiset-välilehdellä olevasta linkistä. Liitä raporttiin seuraavat tiedot:
|
||||
{0}
|
||||
<translation>Skeeman päivitys epäonnistui, lähetä virheraportti Sekalaiset-välilehdellä olevasta linkistä. Liitä raporttiin seuraavat tiedot:
|
||||
{0}
|
||||
{1}</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -2128,4 +2128,4 @@ Poista tietovaraston linkitys ja lisää se uudelleen.</translation>
|
|||
<translation>Salasanojen tulee olla pidempiä kuin 8 merkkiä.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1354,11 +1354,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="75"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Échec de la mise à niveau de la base de donnée, veuillez remplir un rapport de bug en utilisant le lien dans l'onglet Divers avec l'erreur suivante :
|
||||
{0}
|
||||
<translation>Échec de la mise à niveau de la base de donnée, veuillez remplir un rapport de bug en utilisant le lien dans l'onglet Divers avec l'erreur suivante :
|
||||
{0}
|
||||
{1}</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -2125,4 +2125,4 @@ Essayez de dissocier et d'ajouter le dépôt à nouveau.</translation>
|
|||
<translation>Les mots de passe doivent faire plus de 8 caractères.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1210,11 +1210,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="77"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Produciuse u fallo na actualización do esquema, presenta un informe de erro coa ligazón na lapela Varios co seguinte erro:
|
||||
{0}
|
||||
{0}
|
||||
{1}</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -1837,4 +1837,4 @@ Probe a desvincular e engadir de novo o repositorio.</translation>
|
|||
<translation>Os contrasinais deben ter máis de 8 caracteres.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1409,4 +1409,4 @@
|
|||
<translation type="unfinished"/>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1357,8 +1357,8 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="75"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Het schema kan niet worden bijgewerkt. Stel een bugmelding op via de link op het tabblad ‘Overig’. Stuur de volgende informatie mee:
|
||||
|
||||
|
@ -2129,4 +2129,4 @@ Herkoppel je repo.</translation>
|
|||
<translation>De wachtwoorden moeten meer dan 8 tekens bevatten.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1210,11 +1210,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="77"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Сбой обновления схемы. Отправьте сообщение об ошибке по ссылке на вкладке Разное со следующим текстом ошибки:
|
||||
{0}
|
||||
<translation>Сбой обновления схемы. Отправьте сообщение об ошибке по ссылке на вкладке Разное со следующим текстом ошибки:
|
||||
{0}
|
||||
{1}</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
@ -1889,4 +1889,4 @@ Try unlinking and re-adding your repo.</source>
|
|||
<translation>Пароль должен быть длиннее 8 символов.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1357,8 +1357,8 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="75"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Upgrade schémy skončil s chybou, otvorte hlásenie o chybe kliknutím na odkaz na karte Rôzne a skopírujte tento text:
|
||||
{0}
|
||||
|
@ -2128,4 +2128,4 @@ Skúste tento repozitár odpojiť a opäť pridať.</translation>
|
|||
<translation>Heslá musia obsahovať aspoň 8 znakov.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -1210,8 +1210,8 @@
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../../views/import_window.py" line="77"/>
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
<source>Schema upgrade failure, file a bug report with the link in the Misc tab with the following error:
|
||||
{0}
|
||||
{1}</source>
|
||||
<translation>Schemauppgraderingsfel, skicka en felrapport med hjälp av länken i diversefliken och ange följande fel:
|
||||
{0}
|
||||
|
@ -1890,4 +1890,4 @@ Försök avlänka och återansluta ditt förråd.</translation>
|
|||
<translation>Lösenord måste vara längre än 8 tecken.</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
</TS>
|
||||
|
|
|
@ -20,8 +20,17 @@
|
|||
)
|
||||
from vorta.views.main_window import MainWindow
|
||||
|
||||
models = [RepoModel, RepoPassword, BackupProfileModel, SourceFileModel,
|
||||
SettingsModel, ArchiveModel, WifiSettingModel, EventLogModel, SchemaVersion]
|
||||
models = [
|
||||
RepoModel,
|
||||
RepoPassword,
|
||||
BackupProfileModel,
|
||||
SourceFileModel,
|
||||
SettingsModel,
|
||||
ArchiveModel,
|
||||
WifiSettingModel,
|
||||
EventLogModel,
|
||||
SchemaVersion,
|
||||
]
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
|
@ -38,6 +47,7 @@ def qapp(tmpdir_factory):
|
|||
vorta.store.connection.init_db(mock_db)
|
||||
|
||||
from vorta.application import VortaApp
|
||||
|
||||
VortaApp.set_borg_details_action = MagicMock() # Can't use pytest-mock in session scope
|
||||
VortaApp.scheduler = MagicMock()
|
||||
|
||||
|
@ -51,7 +61,12 @@ def qapp(tmpdir_factory):
|
|||
@pytest.fixture(scope='function', autouse=True)
|
||||
def init_db(qapp, qtbot, tmpdir_factory):
|
||||
tmp_db = tmpdir_factory.mktemp('Vorta').join('settings.sqlite')
|
||||
mock_db = SqliteDatabase(str(tmp_db), pragmas={'journal_mode': 'wal', })
|
||||
mock_db = SqliteDatabase(
|
||||
str(tmp_db),
|
||||
pragmas={
|
||||
'journal_mode': 'wal',
|
||||
},
|
||||
)
|
||||
vorta.store.connection.init_db(mock_db)
|
||||
|
||||
default_profile = BackupProfileModel(name='Default')
|
||||
|
@ -72,8 +87,7 @@ def init_db(qapp, qtbot, tmpdir_factory):
|
|||
test_archive1 = ArchiveModel(snapshot_id='99998', name='test-archive1', time=dt(2000, 1, 1, 0, 0), repo=1)
|
||||
test_archive1.save()
|
||||
|
||||
source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo, dir_size=100, dir_files_count=18,
|
||||
path_isdir=True)
|
||||
source_dir = SourceFileModel(dir='/tmp/another', repo=new_repo, dir_size=100, dir_files_count=18, path_isdir=True)
|
||||
source_dir.save()
|
||||
|
||||
qapp.main_window.deleteLater()
|
||||
|
@ -110,6 +124,7 @@ def _read_json(subcommand):
|
|||
stdout = open(f'tests/borg_json_output/{subcommand}_stdout.json')
|
||||
stderr = open(f'tests/borg_json_output/{subcommand}_stderr.json')
|
||||
return stdout, stderr
|
||||
|
||||
return _read_json
|
||||
|
||||
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
from vorta.network_status import darwin
|
||||
|
||||
|
||||
@pytest.mark.parametrize('getpacket_output_name, expected', [
|
||||
('normal_router', False),
|
||||
('phone', True),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
'getpacket_output_name, expected',
|
||||
[
|
||||
('normal_router', False),
|
||||
('phone', True),
|
||||
],
|
||||
)
|
||||
def test_is_network_metered(getpacket_output_name, expected, monkeypatch):
|
||||
def mock_getpacket(device):
|
||||
assert device == 'en0'
|
||||
|
@ -80,7 +83,7 @@ def test_get_network_devices(monkeypatch):
|
|||
domain_name_server (ip_mult): {192.168.43.242}
|
||||
vendor_specific (opaque):
|
||||
0000 41 4e 44 52 4f 49 44 5f 4d 45 54 45 52 45 44 ANDROID_METERED
|
||||
"""
|
||||
""",
|
||||
}
|
||||
|
||||
NETWORKSETUP_OUTPUT = b"""\
|
||||
|
|
|
@ -14,10 +14,7 @@
|
|||
|
||||
@pytest.fixture
|
||||
def mock_adapter():
|
||||
return MagicMock(
|
||||
spec_set=NetworkManagerDBusAdapter,
|
||||
wraps=UncallableNetworkManagerDBusAdapter()
|
||||
)
|
||||
return MagicMock(spec_set=NetworkManagerDBusAdapter, wraps=UncallableNetworkManagerDBusAdapter())
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -29,13 +26,16 @@ def test_is_network_status_available(nm_monitor):
|
|||
assert nm_monitor.is_network_status_available() is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize('global_metered_status, expected', [
|
||||
(NMMetered.UNKNOWN, False),
|
||||
(NMMetered.YES, True),
|
||||
(NMMetered.NO, False),
|
||||
(NMMetered.GUESS_YES, True),
|
||||
(NMMetered.GUESS_NO, False),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
'global_metered_status, expected',
|
||||
[
|
||||
(NMMetered.UNKNOWN, False),
|
||||
(NMMetered.YES, True),
|
||||
(NMMetered.NO, False),
|
||||
(NMMetered.GUESS_YES, True),
|
||||
(NMMetered.GUESS_NO, False),
|
||||
],
|
||||
)
|
||||
def test_is_network_metered(global_metered_status, expected, nm_monitor):
|
||||
nm_monitor._nm.get_global_metered_status.return_value = global_metered_status
|
||||
|
||||
|
@ -44,17 +44,22 @@ def test_is_network_metered(global_metered_status, expected, nm_monitor):
|
|||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('connection_path, connection_type, type_settings, expected', [
|
||||
('/org/freedesktop/NetworkManager/ActiveConnection/1',
|
||||
'802-11-wireless', {'ssid': bytes([84, 69, 83, 84])}, 'TEST'),
|
||||
('/org/freedesktop/NetworkManager/ActiveConnection/2',
|
||||
'802-11-ethernet', {}, None),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
'connection_path, connection_type, type_settings, expected',
|
||||
[
|
||||
(
|
||||
'/org/freedesktop/NetworkManager/ActiveConnection/1',
|
||||
'802-11-wireless',
|
||||
{'ssid': bytes([84, 69, 83, 84])},
|
||||
'TEST',
|
||||
),
|
||||
('/org/freedesktop/NetworkManager/ActiveConnection/2', '802-11-ethernet', {}, None),
|
||||
],
|
||||
)
|
||||
def test_get_current_wifi(connection_path, connection_type, type_settings, expected, nm_monitor):
|
||||
nm_monitor._nm.get_primary_connection_path.return_value = connection_path
|
||||
nm_monitor._nm.get_active_connection_info.return_value = ActiveConnectionInfo(
|
||||
connection='/org/freedesktop/NetworkManager/Settings/12',
|
||||
type=connection_type
|
||||
connection='/org/freedesktop/NetworkManager/Settings/12', type=connection_type
|
||||
)
|
||||
nm_monitor._nm.get_settings.side_effect = [{connection_type: type_settings}]
|
||||
|
||||
|
@ -78,10 +83,12 @@ def test_get_known_wifis(nm_monitor):
|
|||
|
||||
result = nm_monitor.get_known_wifis()
|
||||
|
||||
assert result == [SystemWifiInfo(
|
||||
ssid='TEST',
|
||||
last_connected=datetime(2020, 8, 13, 7, 28, 56),
|
||||
)]
|
||||
assert result == [
|
||||
SystemWifiInfo(
|
||||
ssid='TEST',
|
||||
last_connected=datetime(2020, 8, 13, 7, 28, 56),
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def test_get_known_wifis_with_never_used_connection(nm_monitor):
|
||||
|
@ -93,10 +100,12 @@ def test_get_known_wifis_with_never_used_connection(nm_monitor):
|
|||
|
||||
result = nm_monitor.get_known_wifis()
|
||||
|
||||
assert result == [SystemWifiInfo(
|
||||
ssid='TEST',
|
||||
last_connected=None,
|
||||
)]
|
||||
assert result == [
|
||||
SystemWifiInfo(
|
||||
ssid='TEST',
|
||||
last_connected=None,
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def test_get_known_wifis_partial_failure(nm_monitor):
|
||||
|
@ -114,10 +123,12 @@ def test_get_known_wifis_partial_failure(nm_monitor):
|
|||
|
||||
result = nm_monitor.get_known_wifis()
|
||||
|
||||
assert result == [SystemWifiInfo(
|
||||
ssid='TEST',
|
||||
last_connected=None,
|
||||
)]
|
||||
assert result == [
|
||||
SystemWifiInfo(
|
||||
ssid='TEST',
|
||||
last_connected=None,
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def test_get_known_wifis_with_no_wifi_connections(nm_monitor):
|
||||
|
@ -132,11 +143,14 @@ def test_get_known_wifis_with_no_wifi_connections(nm_monitor):
|
|||
assert result == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ssid_bytes, expected', [
|
||||
([84, 69, 83, 84], 'TEST'),
|
||||
([240, 159, 150, 150], '🖖'),
|
||||
([0, 1, 2, 10, 34, 39], '\\x00\\x01\\x02\\n"\''),
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
'ssid_bytes, expected',
|
||||
[
|
||||
([84, 69, 83, 84], 'TEST'),
|
||||
([240, 159, 150, 150], '🖖'),
|
||||
([0, 1, 2, 10, 34, 39], '\\x00\\x01\\x02\\n"\''),
|
||||
],
|
||||
)
|
||||
def test_decode_ssid(ssid_bytes, expected):
|
||||
result = decode_ssid(ssid_bytes)
|
||||
assert result == expected
|
||||
|
|
|
@ -76,8 +76,7 @@ def test_repo_compact(qapp, qtbot, mocker, borg_json_output):
|
|||
qtbot.mouseClick(tab.compactButton, QtCore.Qt.LeftButton)
|
||||
|
||||
qtbot.waitUntil(
|
||||
lambda: 'compaction freed about 56.00 kB repository space' in main.logText.text(),
|
||||
**pytest._wait_defaults
|
||||
lambda: 'compaction freed about 56.00 kB repository space' in main.logText.text(), **pytest._wait_defaults
|
||||
)
|
||||
vorta.utils.borg_compat.version = '1.1.0'
|
||||
|
||||
|
@ -102,9 +101,7 @@ def psutil_disk_partitions(**kwargs):
|
|||
DiskPartitions = namedtuple('DiskPartitions', ['device', 'mountpoint'])
|
||||
return [DiskPartitions('borgfs', '/tmp')]
|
||||
|
||||
monkeypatch.setattr(
|
||||
psutil, "disk_partitions", psutil_disk_partitions
|
||||
)
|
||||
monkeypatch.setattr(psutil, "disk_partitions", psutil_disk_partitions)
|
||||
|
||||
main = qapp.main_window
|
||||
tab = main.archiveTab
|
||||
|
@ -116,9 +113,7 @@ def psutil_disk_partitions(**kwargs):
|
|||
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
||||
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
||||
|
||||
monkeypatch.setattr(
|
||||
vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog
|
||||
)
|
||||
monkeypatch.setattr(vorta.views.archive_tab, "choose_file_dialog", choose_file_dialog)
|
||||
|
||||
tab.bmountarchive_clicked()
|
||||
qtbot.waitUntil(lambda: tab.mountErrors.text().startswith('Mounted'), **pytest._wait_defaults)
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
from vorta.views.diff_result import ChangeType, DiffData, DiffTree, FileType, parse_diff_json, parse_diff_lines
|
||||
|
||||
|
||||
@pytest.mark.parametrize('json_mock_file,folder_root', [
|
||||
('diff_archives', 'test'), ('diff_archives_dict_issue', 'Users')])
|
||||
@pytest.mark.parametrize(
|
||||
'json_mock_file,folder_root', [('diff_archives', 'test'), ('diff_archives_dict_issue', 'Users')]
|
||||
)
|
||||
def test_archive_diff(qapp, qtbot, mocker, borg_json_output, json_mock_file, folder_root):
|
||||
main = qapp.main_window
|
||||
tab = main.archiveTab
|
||||
|
@ -27,6 +28,7 @@ def check(feature_name):
|
|||
if feature_name == 'DIFF_JSON_LINES':
|
||||
return False
|
||||
return vorta.utils.BorgCompatibility.check(compat, feature_name)
|
||||
|
||||
mocker.patch.object(vorta.utils.borg_compat, 'check', check)
|
||||
|
||||
selection_model: QItemSelectionModel = tab.archiveTable.selectionModel()
|
||||
|
@ -52,42 +54,74 @@ def check(feature_name):
|
|||
@pytest.mark.parametrize(
|
||||
'line, expected',
|
||||
[
|
||||
('changed link some/changed/link',
|
||||
('some/changed/link', FileType.LINK, ChangeType.CHANGED_LINK, 0, 0,
|
||||
None, None, None)),
|
||||
(' +77.8 kB -77.8 kB some/changed/file',
|
||||
('some/changed/file', FileType.FILE, ChangeType.MODIFIED, 2 * 77800,
|
||||
0, None, None,
|
||||
(77800, 77800))),
|
||||
(' +77.8 kB -77.8 kB [-rw-rw-rw- -> -rw-r--r--] some/changed/file',
|
||||
('some/changed/file', FileType.FILE, ChangeType.MODIFIED, 2 * 77800, 0,
|
||||
('-rw-rw-rw-', '-rw-r--r--'), None, (77800, 77800))),
|
||||
('[-rw-rw-rw- -> -rw-r--r--] some/changed/file',
|
||||
('some/changed/file', FileType.FILE, ChangeType.MODE, 0, 0,
|
||||
('-rw-rw-rw-', '-rw-r--r--'), None, None)),
|
||||
('added directory some/changed/dir',
|
||||
('some/changed/dir', FileType.DIRECTORY, ChangeType.ADDED, 0, 0, None,
|
||||
None, None)),
|
||||
('removed directory some/changed/dir',
|
||||
('some/changed/dir', FileType.DIRECTORY, ChangeType.REMOVED_DIR, 0, 0,
|
||||
None, None, None)),
|
||||
|
||||
(
|
||||
'changed link some/changed/link',
|
||||
('some/changed/link', FileType.LINK, ChangeType.CHANGED_LINK, 0, 0, None, None, None),
|
||||
),
|
||||
(
|
||||
' +77.8 kB -77.8 kB some/changed/file',
|
||||
('some/changed/file', FileType.FILE, ChangeType.MODIFIED, 2 * 77800, 0, None, None, (77800, 77800)),
|
||||
),
|
||||
(
|
||||
' +77.8 kB -77.8 kB [-rw-rw-rw- -> -rw-r--r--] some/changed/file',
|
||||
(
|
||||
'some/changed/file',
|
||||
FileType.FILE,
|
||||
ChangeType.MODIFIED,
|
||||
2 * 77800,
|
||||
0,
|
||||
('-rw-rw-rw-', '-rw-r--r--'),
|
||||
None,
|
||||
(77800, 77800),
|
||||
),
|
||||
),
|
||||
(
|
||||
'[-rw-rw-rw- -> -rw-r--r--] some/changed/file',
|
||||
('some/changed/file', FileType.FILE, ChangeType.MODE, 0, 0, ('-rw-rw-rw-', '-rw-r--r--'), None, None),
|
||||
),
|
||||
(
|
||||
'added directory some/changed/dir',
|
||||
('some/changed/dir', FileType.DIRECTORY, ChangeType.ADDED, 0, 0, None, None, None),
|
||||
),
|
||||
(
|
||||
'removed directory some/changed/dir',
|
||||
('some/changed/dir', FileType.DIRECTORY, ChangeType.REMOVED_DIR, 0, 0, None, None, None),
|
||||
),
|
||||
# Example from https://github.com/borgbase/vorta/issues/521
|
||||
('[user:user -> nfsnobody:nfsnobody] home/user/arrays/test.txt',
|
||||
('home/user/arrays/test.txt', FileType.FILE, ChangeType.OWNER, 0, 0,
|
||||
None, ('user', 'user', 'nfsnobody', 'nfsnobody'), None)),
|
||||
|
||||
(
|
||||
'[user:user -> nfsnobody:nfsnobody] home/user/arrays/test.txt',
|
||||
(
|
||||
'home/user/arrays/test.txt',
|
||||
FileType.FILE,
|
||||
ChangeType.OWNER,
|
||||
0,
|
||||
0,
|
||||
None,
|
||||
('user', 'user', 'nfsnobody', 'nfsnobody'),
|
||||
None,
|
||||
),
|
||||
),
|
||||
# Very short owner change, to check stripping whitespace from file path
|
||||
('[a:a -> b:b] home/user/arrays/test.txt',
|
||||
('home/user/arrays/test.txt', FileType.FILE, ChangeType.OWNER, 0, 0,
|
||||
None, ('a', 'a', 'b', 'b'), None)),
|
||||
|
||||
(
|
||||
'[a:a -> b:b] home/user/arrays/test.txt',
|
||||
('home/user/arrays/test.txt', FileType.FILE, ChangeType.OWNER, 0, 0, None, ('a', 'a', 'b', 'b'), None),
|
||||
),
|
||||
# All file-related changes in one test
|
||||
(' +77.8 kB -800 B [user:user -> nfsnobody:nfsnobody] [-rw-rw-rw- -> -rw-r--r--] home/user/arrays/test.txt',
|
||||
('home/user/arrays/test.txt', FileType.FILE, ChangeType.OWNER,
|
||||
77800 + 800, 77000, ('-rw-rw-rw-', '-rw-r--r--'),
|
||||
('user', 'user', 'nfsnobody', 'nfsnobody'), (77800, 800))),
|
||||
])
|
||||
(
|
||||
' +77.8 kB -800 B [user:user -> nfsnobody:nfsnobody] [-rw-rw-rw- -> -rw-r--r--] home/user/arrays/test.txt',
|
||||
(
|
||||
'home/user/arrays/test.txt',
|
||||
FileType.FILE,
|
||||
ChangeType.OWNER,
|
||||
77800 + 800,
|
||||
77000,
|
||||
('-rw-rw-rw-', '-rw-r--r--'),
|
||||
('user', 'user', 'nfsnobody', 'nfsnobody'),
|
||||
(77800, 800),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_archive_diff_parser(line, expected):
|
||||
model = DiffTree()
|
||||
model.setMode(model.DisplayMode.FLAT)
|
||||
|
@ -103,113 +137,110 @@ def test_archive_diff_parser(line, expected):
|
|||
@pytest.mark.parametrize(
|
||||
'line, expected',
|
||||
[
|
||||
({
|
||||
'path': 'some/changed/link',
|
||||
'changes': [{
|
||||
'type': 'changed link'
|
||||
}]
|
||||
}, ('some/changed/link', FileType.LINK, ChangeType.CHANGED_LINK, 0, 0,
|
||||
None, None, None)),
|
||||
({
|
||||
'path': 'some/changed/file',
|
||||
'changes': [{
|
||||
'type': 'modified',
|
||||
'added': 77800,
|
||||
'removed': 77800
|
||||
}]
|
||||
}, ('some/changed/file', FileType.FILE, ChangeType.MODIFIED, 2 * 77800,
|
||||
0, None, None, (77800, 77800))),
|
||||
({
|
||||
'path':
|
||||
'some/changed/file',
|
||||
'changes': [{
|
||||
'type': 'modified',
|
||||
'added': 77800,
|
||||
'removed': 800
|
||||
}, {
|
||||
'type': 'mode',
|
||||
'old_mode': '-rw-rw-rw-',
|
||||
'new_mode': '-rw-r--r--'
|
||||
}]
|
||||
}, ('some/changed/file', FileType.FILE, ChangeType.MODIFIED,
|
||||
77800 + 800, 77000, ('-rw-rw-rw-', '-rw-r--r--'), None,
|
||||
(77800, 800))),
|
||||
({
|
||||
'path':
|
||||
'some/changed/file',
|
||||
'changes': [{
|
||||
'type': 'mode',
|
||||
'old_mode': '-rw-rw-rw-',
|
||||
'new_mode': '-rw-r--r--'
|
||||
}]
|
||||
}, ('some/changed/file', FileType.FILE, ChangeType.MODE, 0, 0,
|
||||
('-rw-rw-rw-', '-rw-r--r--'), None, None)),
|
||||
({
|
||||
'path': 'some/changed/dir',
|
||||
'changes': [{
|
||||
'type': 'added directory'
|
||||
}]
|
||||
}, ('some/changed/dir', FileType.DIRECTORY, ChangeType.ADDED, 0, 0,
|
||||
None, None, None)),
|
||||
({
|
||||
'path': 'some/changed/dir',
|
||||
'changes': [{
|
||||
'type': 'removed directory'
|
||||
}]
|
||||
}, ('some/changed/dir', FileType.DIRECTORY, ChangeType.REMOVED_DIR, 0,
|
||||
0, None, None, None)),
|
||||
|
||||
(
|
||||
{'path': 'some/changed/link', 'changes': [{'type': 'changed link'}]},
|
||||
('some/changed/link', FileType.LINK, ChangeType.CHANGED_LINK, 0, 0, None, None, None),
|
||||
),
|
||||
(
|
||||
{'path': 'some/changed/file', 'changes': [{'type': 'modified', 'added': 77800, 'removed': 77800}]},
|
||||
('some/changed/file', FileType.FILE, ChangeType.MODIFIED, 2 * 77800, 0, None, None, (77800, 77800)),
|
||||
),
|
||||
(
|
||||
{
|
||||
'path': 'some/changed/file',
|
||||
'changes': [
|
||||
{'type': 'modified', 'added': 77800, 'removed': 800},
|
||||
{'type': 'mode', 'old_mode': '-rw-rw-rw-', 'new_mode': '-rw-r--r--'},
|
||||
],
|
||||
},
|
||||
(
|
||||
'some/changed/file',
|
||||
FileType.FILE,
|
||||
ChangeType.MODIFIED,
|
||||
77800 + 800,
|
||||
77000,
|
||||
('-rw-rw-rw-', '-rw-r--r--'),
|
||||
None,
|
||||
(77800, 800),
|
||||
),
|
||||
),
|
||||
(
|
||||
{
|
||||
'path': 'some/changed/file',
|
||||
'changes': [{'type': 'mode', 'old_mode': '-rw-rw-rw-', 'new_mode': '-rw-r--r--'}],
|
||||
},
|
||||
('some/changed/file', FileType.FILE, ChangeType.MODE, 0, 0, ('-rw-rw-rw-', '-rw-r--r--'), None, None),
|
||||
),
|
||||
(
|
||||
{'path': 'some/changed/dir', 'changes': [{'type': 'added directory'}]},
|
||||
('some/changed/dir', FileType.DIRECTORY, ChangeType.ADDED, 0, 0, None, None, None),
|
||||
),
|
||||
(
|
||||
{'path': 'some/changed/dir', 'changes': [{'type': 'removed directory'}]},
|
||||
('some/changed/dir', FileType.DIRECTORY, ChangeType.REMOVED_DIR, 0, 0, None, None, None),
|
||||
),
|
||||
# Example from https://github.com/borgbase/vorta/issues/521
|
||||
({
|
||||
'path':
|
||||
'home/user/arrays/test.txt',
|
||||
'changes': [{
|
||||
'type': 'owner',
|
||||
'old_user': 'user',
|
||||
'new_user': 'nfsnobody',
|
||||
'old_group': 'user',
|
||||
'new_group': 'nfsnobody'
|
||||
}]
|
||||
}, ('home/user/arrays/test.txt', FileType.FILE, ChangeType.OWNER, 0, 0,
|
||||
None, ('user', 'user', 'nfsnobody', 'nfsnobody'), None)),
|
||||
|
||||
(
|
||||
{
|
||||
'path': 'home/user/arrays/test.txt',
|
||||
'changes': [
|
||||
{
|
||||
'type': 'owner',
|
||||
'old_user': 'user',
|
||||
'new_user': 'nfsnobody',
|
||||
'old_group': 'user',
|
||||
'new_group': 'nfsnobody',
|
||||
}
|
||||
],
|
||||
},
|
||||
(
|
||||
'home/user/arrays/test.txt',
|
||||
FileType.FILE,
|
||||
ChangeType.OWNER,
|
||||
0,
|
||||
0,
|
||||
None,
|
||||
('user', 'user', 'nfsnobody', 'nfsnobody'),
|
||||
None,
|
||||
),
|
||||
),
|
||||
# Very short owner change, to check stripping whitespace from file path
|
||||
({
|
||||
'path':
|
||||
'home/user/arrays/test.txt',
|
||||
'changes': [{
|
||||
'type': 'owner',
|
||||
'old_user': 'a',
|
||||
'new_user': 'b',
|
||||
'old_group': 'a',
|
||||
'new_group': 'b'
|
||||
}]
|
||||
}, ('home/user/arrays/test.txt', FileType.FILE, ChangeType.OWNER, 0, 0,
|
||||
None, ('a', 'a', 'b', 'b'), None)),
|
||||
|
||||
(
|
||||
{
|
||||
'path': 'home/user/arrays/test.txt',
|
||||
'changes': [{'type': 'owner', 'old_user': 'a', 'new_user': 'b', 'old_group': 'a', 'new_group': 'b'}],
|
||||
},
|
||||
('home/user/arrays/test.txt', FileType.FILE, ChangeType.OWNER, 0, 0, None, ('a', 'a', 'b', 'b'), None),
|
||||
),
|
||||
# All file-related changes in one test
|
||||
({
|
||||
'path':
|
||||
'home/user/arrays/test.txt',
|
||||
'changes': [{
|
||||
'type': 'modified',
|
||||
'added': 77800,
|
||||
'removed': 77800
|
||||
}, {
|
||||
'type': 'mode',
|
||||
'old_mode': '-rw-rw-rw-',
|
||||
'new_mode': '-rw-r--r--'
|
||||
}, {
|
||||
'type': 'owner',
|
||||
'old_user': 'user',
|
||||
'new_user': 'nfsnobody',
|
||||
'old_group': 'user',
|
||||
'new_group': 'nfsnobody'
|
||||
}]
|
||||
}, ('home/user/arrays/test.txt', FileType.FILE, ChangeType.OWNER,
|
||||
2 * 77800, 0, ('-rw-rw-rw-', '-rw-r--r--'),
|
||||
('user', 'user', 'nfsnobody', 'nfsnobody'), (77800, 77800))),
|
||||
])
|
||||
(
|
||||
{
|
||||
'path': 'home/user/arrays/test.txt',
|
||||
'changes': [
|
||||
{'type': 'modified', 'added': 77800, 'removed': 77800},
|
||||
{'type': 'mode', 'old_mode': '-rw-rw-rw-', 'new_mode': '-rw-r--r--'},
|
||||
{
|
||||
'type': 'owner',
|
||||
'old_user': 'user',
|
||||
'new_user': 'nfsnobody',
|
||||
'old_group': 'user',
|
||||
'new_group': 'nfsnobody',
|
||||
},
|
||||
],
|
||||
},
|
||||
(
|
||||
'home/user/arrays/test.txt',
|
||||
FileType.FILE,
|
||||
ChangeType.OWNER,
|
||||
2 * 77800,
|
||||
0,
|
||||
('-rw-rw-rw-', '-rw-r--r--'),
|
||||
('user', 'user', 'nfsnobody', 'nfsnobody'),
|
||||
(77800, 77800),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_archive_diff_json_parser(line, expected):
|
||||
model = DiffTree()
|
||||
model.setMode(model.DisplayMode.FLAT)
|
||||
|
|
|
@ -52,9 +52,7 @@ def test_import_fail_not_json(qapp, rootdir, monkeypatch):
|
|||
def getOpenFileName(*args, **kwargs):
|
||||
return [BAD_FILE]
|
||||
|
||||
monkeypatch.setattr(
|
||||
QFileDialog, "getOpenFileName", getOpenFileName
|
||||
)
|
||||
monkeypatch.setattr(QFileDialog, "getOpenFileName", getOpenFileName)
|
||||
|
||||
alert_message = None
|
||||
|
||||
|
@ -62,9 +60,7 @@ def critical(widget, title, message):
|
|||
nonlocal alert_message
|
||||
alert_message = message
|
||||
|
||||
monkeypatch.setattr(
|
||||
QMessageBox, "critical", critical
|
||||
)
|
||||
monkeypatch.setattr(QMessageBox, "critical", critical)
|
||||
|
||||
main = qapp.main_window
|
||||
main.profile_import_action()
|
||||
|
@ -79,9 +75,7 @@ def test_export_success(qapp, qtbot, tmpdir, monkeypatch):
|
|||
def getSaveFileName(*args, **kwargs):
|
||||
return [FILE_PATH]
|
||||
|
||||
monkeypatch.setattr(
|
||||
QFileDialog, "getSaveFileName", getSaveFileName
|
||||
)
|
||||
monkeypatch.setattr(QFileDialog, "getSaveFileName", getSaveFileName)
|
||||
|
||||
main = qapp.main_window
|
||||
main.profile_export_action()
|
||||
|
@ -99,9 +93,7 @@ def test_export_fail_unwritable(qapp, qtbot, tmpdir, monkeypatch):
|
|||
def getSaveFileName(*args, **kwargs):
|
||||
return [FILE_PATH]
|
||||
|
||||
monkeypatch.setattr(
|
||||
QFileDialog, "getSaveFileName", getSaveFileName
|
||||
)
|
||||
monkeypatch.setattr(QFileDialog, "getSaveFileName", getSaveFileName)
|
||||
|
||||
alert_message = None
|
||||
|
||||
|
@ -109,9 +101,7 @@ def critical(widget, title, message):
|
|||
nonlocal alert_message
|
||||
alert_message = message
|
||||
|
||||
monkeypatch.setattr(
|
||||
QMessageBox, "critical", critical
|
||||
)
|
||||
monkeypatch.setattr(QMessageBox, "critical", critical)
|
||||
|
||||
main = qapp.main_window
|
||||
main.profile_export_action()
|
||||
|
|
|
@ -7,15 +7,14 @@
|
|||
|
||||
|
||||
def test_autostart(qapp, qtbot):
|
||||
''' Check if file exists only on Linux, otherwise just check it doesn't crash '''
|
||||
'''Check if file exists only on Linux, otherwise just check it doesn't crash'''
|
||||
main = qapp.main_window
|
||||
main.tabWidget.setCurrentIndex(4)
|
||||
tab = main.miscTab
|
||||
|
||||
def click_autostart():
|
||||
for x in range(0, tab.checkboxLayout.count()):
|
||||
item = tab.checkboxLayout.itemAt(x,
|
||||
QFormLayout.ItemRole.FieldRole)
|
||||
item = tab.checkboxLayout.itemAt(x, QFormLayout.ItemRole.FieldRole)
|
||||
if not item:
|
||||
continue
|
||||
checkbox = item.widget()
|
||||
|
@ -29,14 +28,16 @@ def click_autostart():
|
|||
click_autostart()
|
||||
|
||||
if sys.platform == 'linux':
|
||||
autostart_path = Path(os.environ.get(
|
||||
"XDG_CONFIG_HOME", os.path.expanduser("~") + '/.config') + "/autostart") / "vorta.desktop"
|
||||
autostart_path = (
|
||||
Path(os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~") + '/.config') + "/autostart")
|
||||
/ "vorta.desktop"
|
||||
)
|
||||
qtbot.waitUntil(lambda: autostart_path.exists(), **pytest._wait_defaults)
|
||||
|
||||
with open(autostart_path) as desktop_file:
|
||||
desktop_file_text = desktop_file.read()
|
||||
|
||||
assert (desktop_file_text.startswith("[Desktop Entry]"))
|
||||
assert desktop_file_text.startswith("[Desktop Entry]")
|
||||
|
||||
click_autostart()
|
||||
if sys.platform == 'linux':
|
||||
|
|
|
@ -57,8 +57,9 @@ def test_repo_unlink(qapp, qtbot):
|
|||
|
||||
qtbot.mouseClick(main.createStartBtn, QtCore.Qt.LeftButton)
|
||||
# -1 is the repo id in this test
|
||||
qtbot.waitUntil(lambda: main.progressText.text().startswith('Add a backup repository first.'),
|
||||
**pytest._wait_defaults)
|
||||
qtbot.waitUntil(
|
||||
lambda: main.progressText.text().startswith('Add a backup repository first.'), **pytest._wait_defaults
|
||||
)
|
||||
assert main.progressText.text() == 'Add a backup repository first.'
|
||||
|
||||
|
||||
|
@ -74,7 +75,7 @@ def test_password_autofill(qapp, qtbot):
|
|||
|
||||
qtbot.keyClicks(add_repo_window.repoURL, test_repo_url)
|
||||
|
||||
assert (add_repo_window.passwordLineEdit.text() == password)
|
||||
assert add_repo_window.passwordLineEdit.text() == password
|
||||
|
||||
|
||||
def test_repo_add_success(qapp, qtbot, mocker, borg_json_output):
|
||||
|
@ -93,9 +94,9 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output):
|
|||
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
||||
|
||||
add_repo_window.run()
|
||||
qtbot.waitUntil(lambda: EventLogModel.select()
|
||||
.where(EventLogModel.returncode == 0).count() == 2,
|
||||
**pytest._wait_defaults)
|
||||
qtbot.waitUntil(
|
||||
lambda: EventLogModel.select().where(EventLogModel.returncode == 0).count() == 2, **pytest._wait_defaults
|
||||
)
|
||||
|
||||
assert RepoModel.get(id=2).url == test_repo_url
|
||||
|
||||
|
|
|
@ -56,12 +56,14 @@ def test_schedule_tab(qapp: VortaApp, qtbot, clockmock):
|
|||
profile = BackupProfileModel.get(name=PROFILE_NAME)
|
||||
profile.schedule_make_up_missed = False
|
||||
profile.save()
|
||||
event = EventLogModel(subcommand='create',
|
||||
profile=profile.id,
|
||||
returncode=0,
|
||||
category='scheduled',
|
||||
start_time=last_time,
|
||||
end_time=last_time)
|
||||
event = EventLogModel(
|
||||
subcommand='create',
|
||||
profile=profile.id,
|
||||
returncode=0,
|
||||
category='scheduled',
|
||||
start_time=last_time,
|
||||
end_time=last_time,
|
||||
)
|
||||
event.save()
|
||||
|
||||
qapp.scheduler.set_timer_for_profile(profile.id)
|
||||
|
|
|
@ -25,15 +25,12 @@ def clockmock(monkeypatch):
|
|||
|
||||
def prepare(func):
|
||||
"""Decorator adding common preparation steps."""
|
||||
|
||||
@wraps(func)
|
||||
def do(qapp, qtbot, mocker, borg_json_output):
|
||||
stdout, stderr = borg_json_output('create')
|
||||
popen_result = mocker.MagicMock(stdout=stdout,
|
||||
stderr=stderr,
|
||||
returncode=0)
|
||||
mocker.patch.object(vorta.borg.borg_job,
|
||||
'Popen',
|
||||
return_value=popen_result)
|
||||
popen_result = mocker.MagicMock(stdout=stdout, stderr=stderr, returncode=0)
|
||||
mocker.patch.object(vorta.borg.borg_job, 'Popen', return_value=popen_result)
|
||||
|
||||
return func(qapp, qtbot, mocker, borg_json_output)
|
||||
|
||||
|
@ -81,12 +78,9 @@ def test_simple_schedule(clockmock):
|
|||
profile.schedule_interval_count = 3
|
||||
profile.save()
|
||||
|
||||
event = EventLogModel(subcommand='create',
|
||||
profile=profile.id,
|
||||
returncode=0,
|
||||
category='scheduled',
|
||||
start_time=time,
|
||||
end_time=time)
|
||||
event = EventLogModel(
|
||||
subcommand='create', profile=profile.id, returncode=0, category='scheduled', start_time=time, end_time=time
|
||||
)
|
||||
event.save()
|
||||
|
||||
# test set timer and next_job
|
||||
|
@ -94,7 +88,8 @@ def test_simple_schedule(clockmock):
|
|||
assert len(scheduler.timers) == 1
|
||||
assert scheduler.next_job() == '07:30 ({})'.format(PROFILE_NAME)
|
||||
assert scheduler.next_job_for_profile(profile.id) == ScheduleStatus(
|
||||
ScheduleStatusType.SCHEDULED, dt(2020, 5, 6, 7, 30))
|
||||
ScheduleStatusType.SCHEDULED, dt(2020, 5, 6, 7, 30)
|
||||
)
|
||||
|
||||
# test remove_job and next_job
|
||||
scheduler.remove_job(profile.id)
|
||||
|
@ -109,21 +104,17 @@ def test_simple_schedule(clockmock):
|
|||
[
|
||||
# simple
|
||||
(td(), td(hours=4, minutes=30), 'hours', 3, td(hours=3)),
|
||||
|
||||
# next day
|
||||
(td(), td(hours=4, minutes=30), 'hours', 20, td(hours=20)),
|
||||
|
||||
# passed by less than interval
|
||||
(td(hours=2), td(hours=4, minutes=30), 'hours', 3, td(hours=1)),
|
||||
|
||||
# passed by exactly interval
|
||||
(td(hours=3), td(hours=4, minutes=30), 'hours', 3, td(hours=3)),
|
||||
|
||||
# passed by multiple times the interval
|
||||
(td(hours=7), td(hours=4, minutes=30), 'hours', 3, td(hours=2))
|
||||
])
|
||||
def test_interval(clockmock, passed_time, scheduled, now, unit, count,
|
||||
added_time):
|
||||
(td(hours=7), td(hours=4, minutes=30), 'hours', 3, td(hours=2)),
|
||||
],
|
||||
)
|
||||
def test_interval(clockmock, passed_time, scheduled, now, unit, count, added_time):
|
||||
"""Test scheduling in interval mode."""
|
||||
# setup
|
||||
scheduler = VortaScheduler()
|
||||
|
@ -138,12 +129,14 @@ def test_interval(clockmock, passed_time, scheduled, now, unit, count,
|
|||
profile.schedule_interval_count = count
|
||||
profile.save()
|
||||
|
||||
event = EventLogModel(subcommand='create',
|
||||
profile=profile.id,
|
||||
returncode=0,
|
||||
category='scheduled' if scheduled else '',
|
||||
start_time=time - passed_time,
|
||||
end_time=time - passed_time)
|
||||
event = EventLogModel(
|
||||
subcommand='create',
|
||||
profile=profile.id,
|
||||
returncode=0,
|
||||
category='scheduled' if scheduled else '',
|
||||
start_time=time - passed_time,
|
||||
end_time=time - passed_time,
|
||||
)
|
||||
event.save()
|
||||
|
||||
# run test
|
||||
|
@ -152,19 +145,16 @@ def test_interval(clockmock, passed_time, scheduled, now, unit, count,
|
|||
|
||||
|
||||
@mark.parametrize("scheduled", [True, False])
|
||||
@mark.parametrize(
|
||||
"passed_time",
|
||||
[td(hours=0), td(hours=5),
|
||||
td(hours=14), td(hours=27)])
|
||||
@mark.parametrize("passed_time", [td(hours=0), td(hours=5), td(hours=14), td(hours=27)])
|
||||
@mark.parametrize(
|
||||
"now, hour, minute",
|
||||
[
|
||||
# same day
|
||||
(td(hours=4, minutes=30), 15, 00),
|
||||
|
||||
# next day
|
||||
(td(hours=4, minutes=30), 3, 30),
|
||||
])
|
||||
],
|
||||
)
|
||||
def test_fixed(clockmock, passed_time, scheduled, now, hour, minute):
|
||||
"""Test scheduling in fixed mode."""
|
||||
# setup
|
||||
|
@ -181,12 +171,14 @@ def test_fixed(clockmock, passed_time, scheduled, now, hour, minute):
|
|||
profile.save()
|
||||
|
||||
last_time = time - passed_time
|
||||
event = EventLogModel(subcommand='create',
|
||||
profile=profile.id,
|
||||
returncode=0,
|
||||
category='scheduled' if scheduled else '',
|
||||
start_time=last_time,
|
||||
end_time=last_time)
|
||||
event = EventLogModel(
|
||||
subcommand='create',
|
||||
profile=profile.id,
|
||||
returncode=0,
|
||||
category='scheduled' if scheduled else '',
|
||||
start_time=last_time,
|
||||
end_time=last_time,
|
||||
)
|
||||
event.save()
|
||||
|
||||
# run test
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
|
||||
|
||||
def test_add_folder(qapp, qtbot, mocker, monkeypatch, choose_file_dialog):
|
||||
monkeypatch.setattr(
|
||||
vorta.views.source_tab, "choose_file_dialog", choose_file_dialog
|
||||
)
|
||||
monkeypatch.setattr(vorta.views.source_tab, "choose_file_dialog", choose_file_dialog)
|
||||
main = qapp.main_window
|
||||
main.tabWidget.setCurrentIndex(1)
|
||||
tab = main.sourceTab
|
||||
|
|
|
@ -142,8 +142,7 @@ def test_basic_setup(self):
|
|||
assert item is not None and item.data == 3
|
||||
|
||||
# test parent
|
||||
assert (model.parent(model.indexPath(
|
||||
PurePath('test/subtest'))) == model.indexPath(PurePath('test')))
|
||||
assert model.parent(model.indexPath(PurePath('test/subtest'))) == model.indexPath(PurePath('test'))
|
||||
|
||||
# test index
|
||||
item1 = model.getItem(('test',))
|
||||
|
|