From 4c83d61e9558b36c26389e17f7887ce8a6919311 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 29 Mar 2020 15:57:07 +0200 Subject: [PATCH] Add: initial work on a regression The idea is that when-ever we find anything passing validation where it shouldn't, we add an entry. To make this somewhat sane, a custom regression-language was created where you can target the API in a simple human-readable way. The drawback is that it can be difficult to see what the real calls are that are being made. This is a balance between being able to motivate people to write regressions and being very verbose in case the regression fails. --- .Dockerignore | 1 + .github/workflows/testing.yml | 38 +- .gitignore | 2 + Makefile | 13 + regression/000_success_newgrf.yaml | 38 ++ regression/002_success_new_version.yaml | 28 + regression/010_same_newgrf.yaml | 10 + regression/011_same_version.yaml | 10 + regression/012_not_author.yaml | 11 + regression/020_newgrf_and_scenario.yaml | 7 + regression/021_two_newgrfs.yaml | 7 + regression/100_success_base_sounds.yaml | 22 + regression/101_success_base_music.yaml | 21 + regression/102_success_base_graphics.yaml | 25 + regression/110_invalid_cat.yaml | 8 + regression/111_invalid_md5.yaml | 16 + regression/112_invalid_midi.yaml | 8 + regression/120_missing_md5.yaml | 17 + regression/121_missing_shortname.yaml | 17 + regression/200_success_ai_and_utf8.yaml | 19 + regression/201_success_ai_library.yaml | 18 + regression/202_success_gamescript.yaml | 20 + .../203_success_gamescript_library.yaml | 22 + regression/210_missing_info.yaml | 6 + regression/211_missing_main.yaml | 7 + regression/212_missing_short_name.yaml | 8 + regression/213_missing_base_class.yaml | 8 + regression/220_utf8_without_bom.yaml | 9 + regression/300_success_scenario.yaml | 23 + regression/301_success_heightmap.yaml | 15 + regression/310_invalid_scenario.yaml | 7 + regression/311_invalid_heightmap.yaml | 7 + regression/320_invalid_dependency.yaml | 14 + regression/321_invalid_dependency_md5sum.yaml | 14 + regression/800_discover_self.yaml | 28 + regression/801_discover_content_type.yaml | 15 + regression/801_discover_unique_id.yaml | 16 + regression/900_empty_package.yaml | 11 + regression/910_oversized_name.yaml | 9 + regression/911_oversized_version.yaml | 9 + regression/912_oversized_description.yaml | 9 + regression/913_oversized_url.yaml | 9 + regression/914_oversized_tags.yaml | 11 + regression/915_oversized_packet.yaml | 37 ++ regression/920_invalid_license.yaml | 9 + regression/921_missing_custom_license.yaml | 9 + regression/922_no_license.yaml | 8 + .../923_custom_and_defined_license.yaml | 10 + regression/924_license_with_invalid_utf8.yaml | 11 + regression/930_delete_file.yaml | 8 + regression/931_delete_non_existing_file.yaml | 6 + regression/940_unknown_txt_file.yaml | 7 + regression/941_changelog_wrong_language.yaml | 7 + regression/941_readme_wrong_language.yaml | 7 + regression/942_unknown_extension.yaml | 7 + regression/950_condition_invalid.yaml | 11 + regression/951_condition_wrong_order.yaml | 12 + regression/952_condition_twice.yaml | 12 + regression/changelog.txt | 3 + regression/heightmap.png | Bin 0 -> 653 bytes regression/info-ai.nut | 13 + regression/info-gs.nut | 15 + regression/info-no-base-class.nut | 13 + regression/info-no-short-name.nut | 12 + regression/lang/english.lng | 3 + regression/library-ai.nut | 14 + regression/library-gs.nut | 14 + regression/license.txt | 4 + regression/license_invalid_utf8.txt | 4 + regression/main.nut | 1 + regression/nosound.cat | Bin 0 -> 5475 bytes regression/nosound.obs | 14 + regression/noteon-noteoff.mid | Bin 0 -> 41 bytes regression/noteon-noteoff.obm | 47 ++ regression/readme.txt | 5 + regression/scenario.scn | Bin 0 -> 138710 bytes regression/small-missing-md5.obg | 25 + regression/small-missing-shortname.obg | 25 + regression/small.obg | 26 + regression/utf8_with_bom.nut | 5 + regression/utf8_without_bom.nut | 6 + regression/valid.grf | Bin 0 -> 148 bytes regression/valid.nml | 7 + regression/valid2.grf | Bin 0 -> 148 bytes regression/valid2.nml | 7 + regression/valid3.grf | Bin 0 -> 148 bytes regression/valid3.nml | 7 + regression_runner/__init__.py | 0 regression_runner/__main__.py | 506 ++++++++++++++++++ regression_runner/requirements.base | 6 + regression_runner/requirements.txt | 19 + 91 files changed, 1572 insertions(+), 3 deletions(-) create mode 100644 Makefile create mode 100644 regression/000_success_newgrf.yaml create mode 100644 regression/002_success_new_version.yaml create mode 100644 regression/010_same_newgrf.yaml create mode 100644 regression/011_same_version.yaml create mode 100644 regression/012_not_author.yaml create mode 100644 regression/020_newgrf_and_scenario.yaml create mode 100644 regression/021_two_newgrfs.yaml create mode 100644 regression/100_success_base_sounds.yaml create mode 100644 regression/101_success_base_music.yaml create mode 100644 regression/102_success_base_graphics.yaml create mode 100644 regression/110_invalid_cat.yaml create mode 100644 regression/111_invalid_md5.yaml create mode 100644 regression/112_invalid_midi.yaml create mode 100644 regression/120_missing_md5.yaml create mode 100644 regression/121_missing_shortname.yaml create mode 100644 regression/200_success_ai_and_utf8.yaml create mode 100644 regression/201_success_ai_library.yaml create mode 100644 regression/202_success_gamescript.yaml create mode 100644 regression/203_success_gamescript_library.yaml create mode 100644 regression/210_missing_info.yaml create mode 100644 regression/211_missing_main.yaml create mode 100644 regression/212_missing_short_name.yaml create mode 100644 regression/213_missing_base_class.yaml create mode 100644 regression/220_utf8_without_bom.yaml create mode 100644 regression/300_success_scenario.yaml create mode 100644 regression/301_success_heightmap.yaml create mode 100644 regression/310_invalid_scenario.yaml create mode 100644 regression/311_invalid_heightmap.yaml create mode 100644 regression/320_invalid_dependency.yaml create mode 100644 regression/321_invalid_dependency_md5sum.yaml create mode 100644 regression/800_discover_self.yaml create mode 100644 regression/801_discover_content_type.yaml create mode 100644 regression/801_discover_unique_id.yaml create mode 100644 regression/900_empty_package.yaml create mode 100644 regression/910_oversized_name.yaml create mode 100644 regression/911_oversized_version.yaml create mode 100644 regression/912_oversized_description.yaml create mode 100644 regression/913_oversized_url.yaml create mode 100644 regression/914_oversized_tags.yaml create mode 100644 regression/915_oversized_packet.yaml create mode 100644 regression/920_invalid_license.yaml create mode 100644 regression/921_missing_custom_license.yaml create mode 100644 regression/922_no_license.yaml create mode 100644 regression/923_custom_and_defined_license.yaml create mode 100644 regression/924_license_with_invalid_utf8.yaml create mode 100644 regression/930_delete_file.yaml create mode 100644 regression/931_delete_non_existing_file.yaml create mode 100644 regression/940_unknown_txt_file.yaml create mode 100644 regression/941_changelog_wrong_language.yaml create mode 100644 regression/941_readme_wrong_language.yaml create mode 100644 regression/942_unknown_extension.yaml create mode 100644 regression/950_condition_invalid.yaml create mode 100644 regression/951_condition_wrong_order.yaml create mode 100644 regression/952_condition_twice.yaml create mode 100644 regression/changelog.txt create mode 100644 regression/heightmap.png create mode 100644 regression/info-ai.nut create mode 100644 regression/info-gs.nut create mode 100644 regression/info-no-base-class.nut create mode 100644 regression/info-no-short-name.nut create mode 100644 regression/lang/english.lng create mode 100644 regression/library-ai.nut create mode 100644 regression/library-gs.nut create mode 100644 regression/license.txt create mode 100644 regression/license_invalid_utf8.txt create mode 100644 regression/main.nut create mode 100644 regression/nosound.cat create mode 100644 regression/nosound.obs create mode 100644 regression/noteon-noteoff.mid create mode 100644 regression/noteon-noteoff.obm create mode 100644 regression/readme.txt create mode 100644 regression/scenario.scn create mode 100644 regression/small-missing-md5.obg create mode 100644 regression/small-missing-shortname.obg create mode 100644 regression/small.obg create mode 100644 regression/utf8_with_bom.nut create mode 100644 regression/utf8_without_bom.nut create mode 100644 regression/valid.grf create mode 100644 regression/valid.nml create mode 100644 regression/valid2.grf create mode 100644 regression/valid2.nml create mode 100644 regression/valid3.grf create mode 100644 regression/valid3.nml create mode 100644 regression_runner/__init__.py create mode 100644 regression_runner/__main__.py create mode 100644 regression_runner/requirements.base create mode 100644 regression_runner/requirements.txt diff --git a/.Dockerignore b/.Dockerignore index 3330cac..cde5025 100644 --- a/.Dockerignore +++ b/.Dockerignore @@ -1,5 +1,6 @@ __pycache__/ *.pyc +.coverage /.env /BaNaNaS /data diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 47cf5f2..996f126 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -22,10 +22,14 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - name: Flake8 + - name: Flake8 bananas_api uses: TrueBrain/actions-flake8@master with: path: bananas_api + - name: Flake8 regression_runner + uses: TrueBrain/actions-flake8@master + with: + path: regression_runner black: name: Black @@ -37,8 +41,36 @@ jobs: uses: actions/setup-python@v1 with: python-version: 3.8 - - name: Black + - name: Set up packages run: | python -m pip install --upgrade pip pip install black - black -l 120 --check bananas_api + - name: Black + run: | + black -l 120 --check bananas_api regression_runner + + regression: + name: Regression + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Set up Python 3.8 + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: Set up packages + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install -r regression_runner/requirements.txt + - name: Install tusd + run: | + wget -q https://github.com/tus/tusd/releases/download/v1.1.0/tusd_linux_amd64.tar.gz + mkdir -p tusd + tar xf tusd_linux_amd64.tar.gz -C tusd + sudo mv tusd/tusd_linux_amd64/tusd /usr/bin/tusd + rm -rf tusd_linux_amd64.tar.gz tusd + - name: Regression + run: | + make regression diff --git a/.gitignore b/.gitignore index 3330cac..04f208a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ __pycache__/ *.pyc +.coverage /.env /BaNaNaS /data +/htmlcov /local_storage diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..84f1dc2 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +all: + noop + +coverage: + COVERAGE_FILE="$(shell pwd)/.coverage" python -m regression_runner --coverage regression/*.yaml + coverage report -m + coverage html + +regression: + python -m regression_runner regression/*.yaml + + +.PHONY: all coverage regression diff --git a/regression/000_success_newgrf.yaml b/regression/000_success_newgrf.yaml new file mode 100644 index 0000000..760a82f --- /dev/null +++ b/regression/000_success_newgrf.yaml @@ -0,0 +1,38 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- file-upload: readme.txt +- file-upload: changelog.txt +- api: new-package/update + name: "test--test" + version: "v1" + license: "GPL v2" + description: "My Description" + url: "https://www.openttd.org/" + tags: + - "tag1" + - "tag2" + compatibility: + - name: master + conditions: + - ">= 1.0.0" + - "< 1.10.0" +- api: new-package/info + name: "test--test" + version: "v1" + license: "GPL v2" + description: "My Description" + url: "https://www.openttd.org/" + tags: + - "tag1" + - "tag2" + compatibility: + - name: master + conditions: + - ">= 1.0.0" + - "< 1.10.0" + md5sum-partial: "c81c3d77" + content-type: "newgrf" + unique-id: "4e4d4c01" +- api: new-package/publish diff --git a/regression/002_success_new_version.yaml b/regression/002_success_new_version.yaml new file mode 100644 index 0000000..99b2915 --- /dev/null +++ b/regression/002_success_new_version.yaml @@ -0,0 +1,28 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + name: "test--test" + version: "v2" + license: "GPL v2" + description: "My Description" + url: "https://www.openttd.org/" + tags: + - "tag1" + - "tag2" +- file-upload: valid2.grf +- file-upload: readme.txt +- file-upload: changelog.txt +- api: new-package/info + name: "test--test" + version: "v2" + license: "GPL v2" + description: "My Description" + url: "https://www.openttd.org/" + tags: + - "tag1" + - "tag2" + md5sum-partial: "fc03854a" + content-type: "newgrf" + unique-id: "4e4d4c01" +- api: new-package/publish diff --git a/regression/010_same_newgrf.yaml b/regression/010_same_newgrf.yaml new file mode 100644 index 0000000..4917b14 --- /dev/null +++ b/regression/010_same_newgrf.yaml @@ -0,0 +1,10 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- api: new-package/update + name: "test" + version: "v2" + license: "GPL v2" +- api: new-package/publish + error: "There is already an entry with the same md5sum-partial for this package; this most likely means you are uploading the exact same content." diff --git a/regression/011_same_version.yaml b/regression/011_same_version.yaml new file mode 100644 index 0000000..e18e7a2 --- /dev/null +++ b/regression/011_same_version.yaml @@ -0,0 +1,10 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" +- api: new-package/publish + error: "There is already an entry with the same version for this package." diff --git a/regression/012_not_author.yaml b/regression/012_not_author.yaml new file mode 100644 index 0000000..548493a --- /dev/null +++ b/regression/012_not_author.yaml @@ -0,0 +1,11 @@ +steps: +- api: user/login + username: regression2 +- api: new-package/start +- file-upload: valid3.grf +- api: new-package/update + name: "test" + version: "v3" + license: "GPL v2" +- api: new-package/publish + error: "You do not have permission to upload a new version for this package." diff --git a/regression/020_newgrf_and_scenario.yaml b/regression/020_newgrf_and_scenario.yaml new file mode 100644 index 0000000..62a3081 --- /dev/null +++ b/regression/020_newgrf_and_scenario.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- file-upload: valid2.grf +- api: new-package/publish + error: "More than one newgrf files was detected, where only one was expected." diff --git a/regression/021_two_newgrfs.yaml b/regression/021_two_newgrfs.yaml new file mode 100644 index 0000000..a04ade0 --- /dev/null +++ b/regression/021_two_newgrfs.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid3.grf +- file-upload: scenario.scn +- api: new-package/publish + error: "More than one Content Type was detected, where only one was expected. For example, you are uploading both a NewGRF and a Scenario in the same package. This is not possible." diff --git a/regression/100_success_base_sounds.yaml b/regression/100_success_base_sounds.yaml new file mode 100644 index 0000000..af058f8 --- /dev/null +++ b/regression/100_success_base_sounds.yaml @@ -0,0 +1,22 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: nosound.obs +- file-upload: nosound.cat +- file-upload: license.txt +- file-upload: readme.txt + name: readme_nl.txt +- file-upload: changelog.txt + name: changelog_nl.txt +- api: new-package/update + name: "test" + version: "v1" + license: "Custom" +- api: new-package/info + name: "test" + version: "v1" + license: "Custom" + md5sum-partial: "b16a57bf" + content-type: "base-sounds" + unique-id: "4e554c4c" +- api: new-package/publish diff --git a/regression/101_success_base_music.yaml b/regression/101_success_base_music.yaml new file mode 100644 index 0000000..e81750d --- /dev/null +++ b/regression/101_success_base_music.yaml @@ -0,0 +1,21 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: noteon-noteoff.obm +- file-upload: noteon-noteoff.mid +- file-upload: readme.txt + name: readme_nl_NL.txt +- file-upload: changelog.txt + name: changelog_nl_NL.txt +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" +- api: new-package/info + name: "test" + version: "v1" + license: "GPL v2" + md5sum-partial: "c2c91e76" + content-type: "base-music" + unique-id: "4e4f4e4f" +- api: new-package/publish diff --git a/regression/102_success_base_graphics.yaml b/regression/102_success_base_graphics.yaml new file mode 100644 index 0000000..44e670d --- /dev/null +++ b/regression/102_success_base_graphics.yaml @@ -0,0 +1,25 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: small.obg +- file-upload: valid.grf +- file-upload: valid.grf + name: valid1.grf +- file-upload: valid2.grf +- file-upload: valid3.grf +- file-upload: valid.grf + name: valid4.grf +- file-upload: valid.grf + name: valid5.grf +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" +- api: new-package/info + name: "test" + version: "v1" + license: "GPL v2" + md5sum-partial: "2ee06136" + content-type: "base-graphics" + unique-id: "534d4c4c" +- api: new-package/publish diff --git a/regression/110_invalid_cat.yaml b/regression/110_invalid_cat.yaml new file mode 100644 index 0000000..6322926 --- /dev/null +++ b/regression/110_invalid_cat.yaml @@ -0,0 +1,8 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: nosound.obs +- file-upload: noteon-noteoff.mid + name: nosound.cat +- api: new-package/publish + error: "nosound.cat: Invalid cat header." diff --git a/regression/111_invalid_md5.yaml b/regression/111_invalid_md5.yaml new file mode 100644 index 0000000..55323a4 --- /dev/null +++ b/regression/111_invalid_md5.yaml @@ -0,0 +1,16 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: small.obg +- file-upload: valid.grf +- file-upload: valid.grf + name: valid1.grf +- file-upload: valid.grf + name: valid2.grf +- file-upload: valid3.grf +- file-upload: valid.grf + name: valid4.grf +- file-upload: valid.grf + name: valid5.grf +- api: new-package/publish + error: "valid2.grf: The md5sum doesn't match the one mentioned in small.obg." diff --git a/regression/112_invalid_midi.yaml b/regression/112_invalid_midi.yaml new file mode 100644 index 0000000..746c08d --- /dev/null +++ b/regression/112_invalid_midi.yaml @@ -0,0 +1,8 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: noteon-noteoff.obm +- file-upload: nosound.cat + name: noteon-noteoff.mid +- api: new-package/publish + error: "noteon-noteoff.mid: Invalid MIDI header." diff --git a/regression/120_missing_md5.yaml b/regression/120_missing_md5.yaml new file mode 100644 index 0000000..3f080fb --- /dev/null +++ b/regression/120_missing_md5.yaml @@ -0,0 +1,17 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: small-missing-md5.obg +- file-upload: valid.grf +- file-upload: valid.grf + name: valid1.grf +- file-upload: valid.grf + name: valid2.grf +- file-upload: valid.grf + name: valid3.grf +- file-upload: valid.grf + name: valid4.grf +- file-upload: valid.grf + name: valid5.grf +- api: new-package/publish + error: "small-missing-md5.obg: Option md5s:valid5.grf is missing." diff --git a/regression/121_missing_shortname.yaml b/regression/121_missing_shortname.yaml new file mode 100644 index 0000000..b1cd769 --- /dev/null +++ b/regression/121_missing_shortname.yaml @@ -0,0 +1,17 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: small-missing-shortname.obg +- file-upload: valid.grf +- file-upload: valid.grf + name: valid1.grf +- file-upload: valid.grf + name: valid2.grf +- file-upload: valid.grf + name: valid3.grf +- file-upload: valid.grf + name: valid4.grf +- file-upload: valid.grf + name: valid5.grf +- api: new-package/publish + error: "small-missing-shortname.obg: Option metadata:shortname is missing." diff --git a/regression/200_success_ai_and_utf8.yaml b/regression/200_success_ai_and_utf8.yaml new file mode 100644 index 0000000..8413863 --- /dev/null +++ b/regression/200_success_ai_and_utf8.yaml @@ -0,0 +1,19 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: main.nut +- file-upload: info-ai.nut + name: info.nut +- file-upload: utf8_with_bom.nut +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" +- api: new-package/info + name: "test" + version: "v1" + license: "GPL v2" + md5sum-partial: "82b67279" + content-type: "ai" + unique-id: "52454752" +- api: new-package/publish diff --git a/regression/201_success_ai_library.yaml b/regression/201_success_ai_library.yaml new file mode 100644 index 0000000..7d04c48 --- /dev/null +++ b/regression/201_success_ai_library.yaml @@ -0,0 +1,18 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: main.nut +- file-upload: library-ai.nut + name: library.nut +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" +- api: new-package/info + name: "test" + version: "v1" + license: "GPL v2" + md5sum-partial: "f529a430" + content-type: "ai-library" + unique-id: "52454752" +- api: new-package/publish diff --git a/regression/202_success_gamescript.yaml b/regression/202_success_gamescript.yaml new file mode 100644 index 0000000..f483172 --- /dev/null +++ b/regression/202_success_gamescript.yaml @@ -0,0 +1,20 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: main.nut +- file-upload: info-gs.nut + name: info.nut +- file-upload: lang/english.lng + name: lang/english.txt +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" +- api: new-package/info + name: "test" + version: "v1" + license: "GPL v2" + md5sum-partial: "00ef4fe6" + content-type: "game-script" + unique-id: "52454752" +- api: new-package/publish diff --git a/regression/203_success_gamescript_library.yaml b/regression/203_success_gamescript_library.yaml new file mode 100644 index 0000000..63165c7 --- /dev/null +++ b/regression/203_success_gamescript_library.yaml @@ -0,0 +1,22 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: main.nut +- file-upload: library-gs.nut + name: library.nut +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" + description: |- + Test + Newline +- api: new-package/info + name: "test" + version: "v1" + license: "GPL v2" + md5sum-partial: "49655a23" + content-type: "game-script-library" + unique-id: "52454752" + description: "Test\nNewline" +- api: new-package/publish diff --git a/regression/210_missing_info.yaml b/regression/210_missing_info.yaml new file mode 100644 index 0000000..008e1f9 --- /dev/null +++ b/regression/210_missing_info.yaml @@ -0,0 +1,6 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: main.nut +- api: new-package/publish + error: "Expecting at least a single file defining the Content Type." diff --git a/regression/211_missing_main.yaml b/regression/211_missing_main.yaml new file mode 100644 index 0000000..e0edc1b --- /dev/null +++ b/regression/211_missing_main.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: info-ai.nut + name: info.nut +- api: new-package/publish + error: "Expected exact 1 main-script file(s), but 0 were found." diff --git a/regression/212_missing_short_name.yaml b/regression/212_missing_short_name.yaml new file mode 100644 index 0000000..cde3169 --- /dev/null +++ b/regression/212_missing_short_name.yaml @@ -0,0 +1,8 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: main.nut +- file-upload: info-no-short-name.nut + name: info.nut +- api: new-package/publish + error: "info.nut: Couldn't parse file to find GetShortName() function." diff --git a/regression/213_missing_base_class.yaml b/regression/213_missing_base_class.yaml new file mode 100644 index 0000000..89d8e7d --- /dev/null +++ b/regression/213_missing_base_class.yaml @@ -0,0 +1,8 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: main.nut +- file-upload: info-no-base-class.nut + name: info.nut +- api: new-package/publish + error: "info.nut: Couldn't parse file to find base class." diff --git a/regression/220_utf8_without_bom.yaml b/regression/220_utf8_without_bom.yaml new file mode 100644 index 0000000..5110268 --- /dev/null +++ b/regression/220_utf8_without_bom.yaml @@ -0,0 +1,9 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: main.nut +- file-upload: info-ai.nut + name: info.nut +- file-upload: utf8_without_bom.nut +- api: new-package/publish + error: "utf8_without_bom.nut: File contains UTF-8 characters but doesn't contain UTF-8 BOM. OpenTTD won't load this file correctly. Please save the file with 'UTF-8 BOM' encoding." diff --git a/regression/300_success_scenario.yaml b/regression/300_success_scenario.yaml new file mode 100644 index 0000000..a8b421f --- /dev/null +++ b/regression/300_success_scenario.yaml @@ -0,0 +1,23 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: scenario.scn +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" + dependencies: + - content-type: newgrf + unique-id: 4e4d4c01 + md5sum-partial: c81c3d77 +- api: new-package/info + name: "test" + version: "v1" + license: "GPL v2" + md5sum-partial: "29d58129" + content-type: "scenario" + dependencies: + - content-type: newgrf + unique-id: 4e4d4c01 + md5sum-partial: c81c3d77 +- api: new-package/publish diff --git a/regression/301_success_heightmap.yaml b/regression/301_success_heightmap.yaml new file mode 100644 index 0000000..d088f7a --- /dev/null +++ b/regression/301_success_heightmap.yaml @@ -0,0 +1,15 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: heightmap.png +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" +- api: new-package/info + name: "test" + version: "v1" + license: "GPL v2" + md5sum-partial: "409b021d" + content-type: "heightmap" +- api: new-package/publish diff --git a/regression/310_invalid_scenario.yaml b/regression/310_invalid_scenario.yaml new file mode 100644 index 0000000..b279992 --- /dev/null +++ b/regression/310_invalid_scenario.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: heightmap.png + name: scenario.scn +- api: new-package/publish + error: "scenario.scn: Unknown savegame compression b'\\x89PNG'." diff --git a/regression/311_invalid_heightmap.yaml b/regression/311_invalid_heightmap.yaml new file mode 100644 index 0000000..b4a7d35 --- /dev/null +++ b/regression/311_invalid_heightmap.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: scenario.scn + name: heightmap.png +- api: new-package/publish + error: "heightmap.png: File is not a valid image." diff --git a/regression/320_invalid_dependency.yaml b/regression/320_invalid_dependency.yaml new file mode 100644 index 0000000..ac9f1f8 --- /dev/null +++ b/regression/320_invalid_dependency.yaml @@ -0,0 +1,14 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: scenario.scn +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" + dependencies: + - content-type: newgrf + unique-id: ffffffff + md5sum-partial: ffffffff + error: + dependencies: "Package with unique-id 'ffffffff' does not exist for newgrf." diff --git a/regression/321_invalid_dependency_md5sum.yaml b/regression/321_invalid_dependency_md5sum.yaml new file mode 100644 index 0000000..35890fd --- /dev/null +++ b/regression/321_invalid_dependency_md5sum.yaml @@ -0,0 +1,14 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: scenario.scn +- api: new-package/update + name: "test" + version: "v1" + license: "GPL v2" + dependencies: + - content-type: newgrf + unique-id: 4e4d4c01 + md5sum-partial: ffffffff + error: + dependencies: "No version with md5sum-partial 'ffffffff' exist for newgrf with unique-id '4e4d4c01'." diff --git a/regression/800_discover_self.yaml b/regression/800_discover_self.yaml new file mode 100644 index 0000000..bfe3f54 --- /dev/null +++ b/regression/800_discover_self.yaml @@ -0,0 +1,28 @@ +steps: +- api: user/login +- api: discover/self + packages: + - name: "test--test" + version: "v1" + license: "GPL v2" + description: "My Description" + url: "https://www.openttd.org/" + tags: + - "tag1" + - "tag2" + md5sum-partial: "c81c3d77" + content-type: "newgrf" + unique-id: "4e4d4c01" + availability: "savegames-only" + - name: "test--test" + version: "v2" + license: "GPL v2" + description: "My Description" + url: "https://www.openttd.org/" + tags: + - "tag1" + - "tag2" + md5sum-partial: "fc03854a" + content-type: "newgrf" + unique-id: "4e4d4c01" + availability: "new-games" diff --git a/regression/801_discover_content_type.yaml b/regression/801_discover_content_type.yaml new file mode 100644 index 0000000..3080167 --- /dev/null +++ b/regression/801_discover_content_type.yaml @@ -0,0 +1,15 @@ +steps: +- api: discover/content-type + content-type: "newgrf" + packages: + - name: "test--test" + version: "v2" + license: "GPL v2" + description: "My Description" + url: "https://www.openttd.org/" + tags: + - "tag1" + - "tag2" + md5sum-partial: "fc03854a" + content-type: "newgrf" + unique-id: "4e4d4c01" diff --git a/regression/801_discover_unique_id.yaml b/regression/801_discover_unique_id.yaml new file mode 100644 index 0000000..f6705bd --- /dev/null +++ b/regression/801_discover_unique_id.yaml @@ -0,0 +1,16 @@ +steps: +- api: discover/unique-id + content-type: "newgrf" + unique-id: "4e4d4c01" + packages: + - name: "test--test" + version: "v2" + license: "GPL v2" + description: "My Description" + url: "https://www.openttd.org/" + tags: + - "tag1" + - "tag2" + md5sum-partial: "fc03854a" + content-type: "newgrf" + unique-id: "4e4d4c01" diff --git a/regression/900_empty_package.yaml b/regression/900_empty_package.yaml new file mode 100644 index 0000000..bde1708 --- /dev/null +++ b/regression/900_empty_package.yaml @@ -0,0 +1,11 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/publish + error: "Expecting at least a single file defining the Content Type." +- api: new-package/publish + error: "License is not yet set for this package." +- api: new-package/publish + error: "Version is not yet set for this package." +- api: new-package/publish + error: "Name is not yet set for this package." diff --git a/regression/910_oversized_name.yaml b/regression/910_oversized_name.yaml new file mode 100644 index 0000000..7ad7131 --- /dev/null +++ b/regression/910_oversized_name.yaml @@ -0,0 +1,9 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + name: "12345678901234567890123456789012" + error: + name: "Longer than maximum length 31." +- api: new-package/update + name: "1234567890123456789012345678901" diff --git a/regression/911_oversized_version.yaml b/regression/911_oversized_version.yaml new file mode 100644 index 0000000..e2c1a3e --- /dev/null +++ b/regression/911_oversized_version.yaml @@ -0,0 +1,9 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + version: "1234567890123456" + error: + version: "Longer than maximum length 15." +- api: new-package/update + version: "123456789012345" diff --git a/regression/912_oversized_description.yaml b/regression/912_oversized_description.yaml new file mode 100644 index 0000000..0a06329 --- /dev/null +++ b/regression/912_oversized_description.yaml @@ -0,0 +1,9 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + description: "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012" + error: + description: "Longer than maximum length 511." +- api: new-package/update + description: "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901" diff --git a/regression/913_oversized_url.yaml b/regression/913_oversized_url.yaml new file mode 100644 index 0000000..2f0e0dd --- /dev/null +++ b/regression/913_oversized_url.yaml @@ -0,0 +1,9 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + url: "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" + error: + url: "Longer than maximum length 95." +- api: new-package/update + url: "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345" diff --git a/regression/914_oversized_tags.yaml b/regression/914_oversized_tags.yaml new file mode 100644 index 0000000..77dffcf --- /dev/null +++ b/regression/914_oversized_tags.yaml @@ -0,0 +1,11 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + tags: + - "12345678901234567890123456789012" + error: + tags: "Longer than maximum length 31." +- api: new-package/update + tags: + - "1234567890123456789012345678901" diff --git a/regression/915_oversized_packet.yaml b/regression/915_oversized_packet.yaml new file mode 100644 index 0000000..145d692 --- /dev/null +++ b/regression/915_oversized_packet.yaml @@ -0,0 +1,37 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update +- api: new-package/update + description: "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901" + tags: + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" + - "1234567890123456789012345678901" +- api: new-package/info + error: Entry would exceed OpenTTD packet size; trim down on your tags. diff --git a/regression/920_invalid_license.yaml b/regression/920_invalid_license.yaml new file mode 100644 index 0000000..f1d255f --- /dev/null +++ b/regression/920_invalid_license.yaml @@ -0,0 +1,9 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + name: "test" + version: "test" + license: "My License" + error: + license: "Invalid enum value My License" diff --git a/regression/921_missing_custom_license.yaml b/regression/921_missing_custom_license.yaml new file mode 100644 index 0000000..4373533 --- /dev/null +++ b/regression/921_missing_custom_license.yaml @@ -0,0 +1,9 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + name: "test" + version: "test" + license: "Custom" +- api: new-package/publish + error: "License is set to custom, but no license.txt is uploaded." diff --git a/regression/922_no_license.yaml b/regression/922_no_license.yaml new file mode 100644 index 0000000..9b3c535 --- /dev/null +++ b/regression/922_no_license.yaml @@ -0,0 +1,8 @@ +steps: +- api: user/login +- api: new-package/start +- api: new-package/update + name: "test" + version: "test" +- api: new-package/publish + error: "License is not yet set for this package." diff --git a/regression/923_custom_and_defined_license.yaml b/regression/923_custom_and_defined_license.yaml new file mode 100644 index 0000000..96d5c9b --- /dev/null +++ b/regression/923_custom_and_defined_license.yaml @@ -0,0 +1,10 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: license.txt +- api: new-package/update + name: "test" + version: "test" + license: "GPL v2" +- api: new-package/publish + error: "License is set to GPL v2; this does not require uploading 'license.txt'." diff --git a/regression/924_license_with_invalid_utf8.yaml b/regression/924_license_with_invalid_utf8.yaml new file mode 100644 index 0000000..0125ba9 --- /dev/null +++ b/regression/924_license_with_invalid_utf8.yaml @@ -0,0 +1,11 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: license_invalid_utf8.txt + name: license.txt +- api: new-package/update + name: "test" + version: "test" + license: "Custom" +- api: new-package/publish + error: "license.txt: File contains invalid UTF-8 characters; did you really save it as an UTF-8 file?" diff --git a/regression/930_delete_file.yaml b/regression/930_delete_file.yaml new file mode 100644 index 0000000..23ff24e --- /dev/null +++ b/regression/930_delete_file.yaml @@ -0,0 +1,8 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- api: new-package/delete-file + filename: valid.grf +- api: new-package/publish + error: "Expecting at least a single file defining the Content Type." diff --git a/regression/931_delete_non_existing_file.yaml b/regression/931_delete_non_existing_file.yaml new file mode 100644 index 0000000..06b977f --- /dev/null +++ b/regression/931_delete_non_existing_file.yaml @@ -0,0 +1,6 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- api: new-package/delete-file + uuid: 1234 diff --git a/regression/940_unknown_txt_file.yaml b/regression/940_unknown_txt_file.yaml new file mode 100644 index 0000000..67748b6 --- /dev/null +++ b/regression/940_unknown_txt_file.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: readme.txt + name: somefile.txt +- api: new-package/publish + error: "somefile.txt: Could not recognise this file; possibly the extension is wrong?" diff --git a/regression/941_changelog_wrong_language.yaml b/regression/941_changelog_wrong_language.yaml new file mode 100644 index 0000000..7ae4cf9 --- /dev/null +++ b/regression/941_changelog_wrong_language.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: changelog.txt + name: changelog_NL.txt +- api: new-package/publish + error: "changelog_NL.txt: Could not recognise this file; possibly the extension is wrong?" diff --git a/regression/941_readme_wrong_language.yaml b/regression/941_readme_wrong_language.yaml new file mode 100644 index 0000000..b4c0dda --- /dev/null +++ b/regression/941_readme_wrong_language.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: readme.txt + name: readme_NL.txt +- api: new-package/publish + error: "readme_NL.txt: Could not recognise this file; possibly the extension is wrong?" diff --git a/regression/942_unknown_extension.yaml b/regression/942_unknown_extension.yaml new file mode 100644 index 0000000..a62134e --- /dev/null +++ b/regression/942_unknown_extension.yaml @@ -0,0 +1,7 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: readme.txt + name: somefile.ppp +- api: new-package/publish + error: "somefile.ppp: Could not recognise this file; possibly the extension is wrong?" diff --git a/regression/950_condition_invalid.yaml b/regression/950_condition_invalid.yaml new file mode 100644 index 0000000..00f73cf --- /dev/null +++ b/regression/950_condition_invalid.yaml @@ -0,0 +1,11 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- api: new-package/update + compatibility: + - name: master + conditions: + - "! 1.9.0" + error: + compatibility.conditions: "Condition can only mark the first client-version this version does or doesn't work for; expected '>= VERSION' or '< VERSION', got '! 1.9.0'." diff --git a/regression/951_condition_wrong_order.yaml b/regression/951_condition_wrong_order.yaml new file mode 100644 index 0000000..709e6ab --- /dev/null +++ b/regression/951_condition_wrong_order.yaml @@ -0,0 +1,12 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- api: new-package/update + compatibility: + - name: master + conditions: + - "< 1.9.0" + - ">= 1.8.0" + error: + compatibility.conditions: "First condition can only mark the first client-version this version does work for; expected '>= VERSION', got '< 1.9.0'." diff --git a/regression/952_condition_twice.yaml b/regression/952_condition_twice.yaml new file mode 100644 index 0000000..553d1bb --- /dev/null +++ b/regression/952_condition_twice.yaml @@ -0,0 +1,12 @@ +steps: +- api: user/login +- api: new-package/start +- file-upload: valid.grf +- api: new-package/update + compatibility: + - name: master + conditions: + - ">= 1.9.0" + - ">= 1.8.0" + error: + compatibility.conditions: "Second condition can only mark the first client-version this version doesn't work for; expected '< VERSION', got '>= 1.9.0'." diff --git a/regression/changelog.txt b/regression/changelog.txt new file mode 100644 index 0000000..2a0dd91 --- /dev/null +++ b/regression/changelog.txt @@ -0,0 +1,3 @@ +This is a changelog designed for the regression test. + +We changed all the ✈ into 🚒 for the README. diff --git a/regression/heightmap.png b/regression/heightmap.png new file mode 100644 index 0000000000000000000000000000000000000000..64afb74b8f5320ac016773829cf99bef3bbe60b1 GIT binary patch literal 653 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgga7H)P`PJfmi4h#%Tyq+$OAr-gY z-Zcz5Y#`y1ID6srclBQP8MIP+)P$?{zc*!h@o9bd>fW_;ju-xssnAL8>Hq)#li1du zar)2ZthbN5{&cP;XTrIk=`Vi2uh4sbia}<!p%4wVV-38+3WTGqmZmG%+k- zXJB_&!CvuQScYM0?t@$ZUo$S^+t8NxV;X}1!xx4J3>=&Z`_&m7*$ey~LKtQpDB#!= z|I@1BgHXZ`Bd~nNd!{dph3o=s%}g73pD@hh-N4cSG4&+lHSXoD?XnN{v6lEZ$Tcuu zsb=74RA6|)cz{trgdvJ--i{}{oBFpz`?@kz|X)33|TI|2kR2N8y<$U zK6sqK#{hCge{#=3#t;7dAN0Nywgs@wDE{@xL-E3gw@e(33=Rw&AGtMtzg?aass~Cd N44$rjF6*2UngDUE;gJ9U literal 0 HcmV?d00001 diff --git a/regression/info-ai.nut b/regression/info-ai.nut new file mode 100644 index 0000000..3a75d4c --- /dev/null +++ b/regression/info-ai.nut @@ -0,0 +1,13 @@ +class Regression extends AIInfo +{ + function GetAuthor() { return "Regression"; } + function GetName() { return "Regression"; } + function GetDescription() { return "Regression"; } + function GetVersion() { return 1; } + function GetDate() { return "2020-02-02"; } + function GetShortName() { return "REGR"; } + function CreateInstance() { return "Regression"; } + function GetAPIVersion() { return "1.0"; } +} + +RegisterAI(Regression()); diff --git a/regression/info-gs.nut b/regression/info-gs.nut new file mode 100644 index 0000000..407dd6c --- /dev/null +++ b/regression/info-gs.nut @@ -0,0 +1,15 @@ +ο»Ώclass Regression extends GSInfo +{ + function GetAuthor() { return "Regression"; } + function GetName() { return "Regression"; } + function GetDescription() { return "Regression"; } + function GetVersion() { return 1; } + function GetDate() { return "2020-02-02"; } + function GetShortName() { return /* Test */ "REGR"; } + function CreateInstance() { return "Regression"; } + function GetAPIVersion() { return "1.3"; } +} + +RegisterGS(Regression()); + +/* For you, an UTF-8 bus: 🚌 */ diff --git a/regression/info-no-base-class.nut b/regression/info-no-base-class.nut new file mode 100644 index 0000000..077120a --- /dev/null +++ b/regression/info-no-base-class.nut @@ -0,0 +1,13 @@ +class Regression +{ + function GetAuthor() { return "Regression"; } + function GetName() { return "Regression"; } + function GetDescription() { return "Regression"; } + function GetVersion() { return 1; } + function GetDate() { return "2020-02-02"; } + function GetShortName() { return "REGR"; } + function CreateInstance() { return "Regression"; } + function GetAPIVersion() { return "1.0"; } +} + +RegisterAI(Regression()); diff --git a/regression/info-no-short-name.nut b/regression/info-no-short-name.nut new file mode 100644 index 0000000..23da749 --- /dev/null +++ b/regression/info-no-short-name.nut @@ -0,0 +1,12 @@ +class Regression extends AIInfo +{ + function GetAuthor() { return "Regression"; } + function GetName() { return "Regression"; } + function GetDescription() { return "Regression"; } + function GetVersion() { return 1; } + function GetDate() { return "2020-02-02"; } + function CreateInstance() { return "Regression"; } + function GetAPIVersion() { return "1.0"; } +} + +RegisterAI(Regression()); diff --git a/regression/lang/english.lng b/regression/lang/english.lng new file mode 100644 index 0000000..6eade02 --- /dev/null +++ b/regression/lang/english.lng @@ -0,0 +1,3 @@ +##grflangid en_GB +STR_REGRESSION_NAME :NML regression test +STR_REGRESSION_DESC :A test newgrf testing NML diff --git a/regression/library-ai.nut b/regression/library-ai.nut new file mode 100644 index 0000000..b06a66d --- /dev/null +++ b/regression/library-ai.nut @@ -0,0 +1,14 @@ +class Regression extends AILibrary +{ + function GetAuthor() { return "Regression"; } + function GetName() { return "Regression"; } + function GetDescription() { return "Regression"; } + function GetVersion() { return 1; } + function GetDate() { return "2020-02-02"; } + function GetShortName() { return // "WRON"; } + "REGR"; } + function CreateInstance() { return "Regression"; } + function GetCategory() { return "Regression"; } +} + +RegisterLibrary(Regression()); diff --git a/regression/library-gs.nut b/regression/library-gs.nut new file mode 100644 index 0000000..b85fb08 --- /dev/null +++ b/regression/library-gs.nut @@ -0,0 +1,14 @@ +class Regression extends GSLibrary +{ + function GetAuthor() { return "Regression"; } + function GetName() { return "Regression"; } + function GetDescription() { return "Regression"; } + function GetVersion() { return 1; } + function GetDate() { return "2020-02-02"; } + // function GetShortName() { return "WRON"; } + function GetShortName() { return "REGR"; } + function CreateInstance() { return "Regression"; } + function GetCategory() { return "Regression"; } +} + +RegisterLibrary(Regression()); diff --git a/regression/license.txt b/regression/license.txt new file mode 100644 index 0000000..1e148ad --- /dev/null +++ b/regression/license.txt @@ -0,0 +1,4 @@ +This license is meant as part of the regression set, and is in fact not really a license. +It is just here to validate what happens if we attach a custom license to an upload. + +Here, have a ship (🚒) as nice addition to this license file. diff --git a/regression/license_invalid_utf8.txt b/regression/license_invalid_utf8.txt new file mode 100644 index 0000000..c4dc133 --- /dev/null +++ b/regression/license_invalid_utf8.txt @@ -0,0 +1,4 @@ +This license file is not a valid UTF-8 file, designed to make a regression fail. + +Here it is: + ‘ \ No newline at end of file diff --git a/regression/main.nut b/regression/main.nut new file mode 100644 index 0000000..b444729 --- /dev/null +++ b/regression/main.nut @@ -0,0 +1 @@ +/* A nearly empty file. All you got is this pound (£) sign. This file is saved in latin-1 encoding. */ diff --git a/regression/nosound.cat b/regression/nosound.cat new file mode 100644 index 0000000000000000000000000000000000000000..5ced0368ed2ebe8d610b443962fa13a61375ac5a GIT binary patch literal 5475 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 z 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

!#z?c!mxx z5@w_NUk5FoT%`<`xW-%r318ur&YzD-?V9}E>kFwLA#s2HSJ}+ zH9LMNJGfM2@%k{x^4r1H7qGnYWyR;A{k<01rDRmBa0X+0%M#pa`0zY9!;$x*##zgJ z|HI{gdpg3K^lc_2E%f}}RdBiErSdW*Xz~2)w6R~eogI7`Nxb%0DrhiX>HbRJe@+}b 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 I0irwEE(mGiqW}N^ literal 0 HcmV?d00001 diff --git a/regression/small-missing-md5.obg b/regression/small-missing-md5.obg new file mode 100644 index 0000000..dd7af37 --- /dev/null +++ b/regression/small-missing-md5.obg @@ -0,0 +1,25 @@ +[metadata] +name = Small +shortname = SMLL +version = 1 +palette = Windows +blitter = 32bpp +description = Small Base Graphics + +[files] +base = valid.grf +arctic = valid1.grf +tropical = valid2.grf +logos = valid3.grf +toyland = valid4.grf +extra = valid5.grf + +[md5s] +valid.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid1.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid2.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid3.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid4.grf = c81c3d77aaec48d1a264c6fd170c2657 + +[origin] +default = Please redownload from official source. diff --git a/regression/small-missing-shortname.obg b/regression/small-missing-shortname.obg new file mode 100644 index 0000000..fe5eda1 --- /dev/null +++ b/regression/small-missing-shortname.obg @@ -0,0 +1,25 @@ +[metadata] +name = Small +version = 1 +palette = Windows +blitter = 32bpp +description = Small Base Graphics + +[files] +base = valid.grf +arctic = valid1.grf +tropical = valid2.grf +logos = valid3.grf +toyland = valid4.grf +extra = valid5.grf + +[md5s] +valid.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid1.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid2.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid3.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid4.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid5.grf = c81c3d77aaec48d1a264c6fd170c2657 + +[origin] +default = Please redownload from official source. diff --git a/regression/small.obg b/regression/small.obg new file mode 100644 index 0000000..855a9d3 --- /dev/null +++ b/regression/small.obg @@ -0,0 +1,26 @@ +[metadata] +name = Small +shortname = SMLL +version = 1 +palette = Windows +blitter = 32bpp +description = Small Base Graphics + +[files] +base = valid.grf +arctic = valid1.grf +tropical = valid2.grf +logos = valid3.grf +toyland = valid4.grf +extra = valid5.grf + +[md5s] +valid.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid1.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid2.grf = fc03854a02985df2d6a263008ad1977f +valid3.grf = d2e3e47c05f9140c9ddd5e0be0b275bd +valid4.grf = c81c3d77aaec48d1a264c6fd170c2657 +valid5.grf = c81c3d77aaec48d1a264c6fd170c2657 + +[origin] +default = Please redownload from official source. diff --git a/regression/utf8_with_bom.nut b/regression/utf8_with_bom.nut new file mode 100644 index 0000000..47f7491 --- /dev/null +++ b/regression/utf8_with_bom.nut @@ -0,0 +1,5 @@ +ο»Ώ/* + This is a valid UTF-8 file and with a BOM. +*/ + +/* A train: πŸš† */ diff --git a/regression/utf8_without_bom.nut b/regression/utf8_without_bom.nut new file mode 100644 index 0000000..e77dce2 --- /dev/null +++ b/regression/utf8_without_bom.nut @@ -0,0 +1,6 @@ +/* + This is a valid UTF-8 file but without a BOM. + Currently, OpenTTD cannot read files like that. +*/ + +/* A train: πŸš† */ diff --git a/regression/valid.grf b/regression/valid.grf new file mode 100644 index 0000000000000000000000000000000000000000..c183e0c59e8e10c7eb2ca9803a1ce9525af36f63 GIT binary patch literal 148 zcmZQza1U~8;^mU!YGMEa79jr51SHHr3=wBfKR17;u%KW+kOTvRldq>=7?kN3;26XR z6bf+k31(z)baL_u0rD*v7)(G~IXL`$eHejQp(r)ID7CmaGe1wEB(=DN!4XU;RYkm(oT z7z7k^3UKrZW@K=5a`FiQ@+}w`On|cgIXL`$eHejQp(r)ID7CmaGe1wEB(=DN!4XU; W0ldq>=7)T9}=@;M_ z#0aDV9DRZr862IQd_sVH3kC)gpzMDR4nJQXMj%!wN=+|HEiTT?&r>K#EiPej1XBum VspaWKX<&9{Ub+HMCD>RH0RTRiAO-*c literal 0 HcmV?d00001 diff --git a/regression/valid3.nml b/regression/valid3.nml new file mode 100644 index 0000000..65c99b9 --- /dev/null +++ b/regression/valid3.nml @@ -0,0 +1,7 @@ +grf { + grfid: "NML\1"; + name: string(STR_REGRESSION_NAME); + desc: string(STR_REGRESSION_DESC); + version: 2; + min_compatible_version: 0; +} diff --git a/regression_runner/__init__.py b/regression_runner/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/regression_runner/__main__.py b/regression_runner/__main__.py new file mode 100644 index 0000000..205a9b1 --- /dev/null +++ b/regression_runner/__main__.py @@ -0,0 +1,506 @@ +import aiohttp +import asyncio +import click +import coloredlogs +import ctypes +import logging +import os +import signal +import sys +import verboselogs +import yaml + +from collections.abc import Mapping +from ctypes.util import find_library +from tempfile import TemporaryDirectory +from tusclient.client import TusClient + +log = verboselogs.VerboseLogger(__name__) + +CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]} + +auth_headers = {} +startup_event = asyncio.Event() +session = None +python_proc = None +token = "${TOKEN}" +current_regression = "" + + +class RegressionFailure(Exception): + pass + + +class DefinitionFailure(Exception): + pass + + +async def api_call(request_command, url, json=None, silent=False): + if request_command == "GET": + return await session.get(f"http://127.0.0.1:8080{url}", headers=auth_headers) + if request_command == "POST": + return await session.post(f"http://127.0.0.1:8080{url}", json=json, headers=auth_headers) + if request_command == "PUT": + return await session.put(f"http://127.0.0.1:8080{url}", json=json, headers=auth_headers) + if request_command == "DELETE": + return await session.delete(f"http://127.0.0.1:8080{url}", headers=auth_headers) + + raise DefinitionFailure(f"Unknown request-command {request_command}") + + +def validate_keys(step, fields): + for key in step: + if key not in fields and key != "api": + raise DefinitionFailure(f"Found key '{key}' in definition, which was not expected") + + +def match_package_in_list(packages_to_match, packages_to_match_to): + for package in packages_to_match: + for check_package in packages_to_match_to: + for version in check_package["versions"]: + for field in package.keys(): + if field not in ("version", "license", "md5sum-partial", "availability"): + continue + + if version.get(field) != package[field]: + break + else: + # All fields were identical, so we have a match + break + else: + raise RegressionFailure(f"Couldn't find package in discover self; package={package}") + + for field in package.keys(): + if field in ("version", "license", "md5sum-partial", "availability"): + continue + + if check_package.get(field) != package[field]: + break + else: + # All fields were identical, so we have a match + break + else: + raise RegressionFailure(f"Couldn't find package in discover self; package={package}") + + +async def handle_user_login(step): + validate_keys(step, ["api", "username"]) + + result = await api_call("GET", "/user/login?method=developer") + + if result.status != 200: + raise RegressionFailure(f"Couldn't login; status_code={result.status}") + + data = await result.json() + auth_headers["Authorization"] = f"Bearer {data['bearer-token']}" + + username = step.get("username", "regression") + result = await api_call("POST", "/user/developer", json={"username": username}) + + if result.status != 204: + raise RegressionFailure(f"Couldn't login; status_code={result.status}") + + log.info(f"Logged in as {username}") + + +async def handle_user_logout(step): + validate_keys(step, ["api"]) + + result = await api_call("GET", "/user/logout") + + if result.status != 204: + raise RegressionFailure(f"Couldn't logout; status_code={result.status}") + + del auth_headers["Authorization"] + + +async def handle_discover_self(step): + validate_keys(step, ["api", "packages"]) + + result = await api_call("GET", "/package/self") + + if result.status != 200: + raise RegressionFailure(f"Couldn't find package in discover self; status_code={result.status}") + + data = await result.json() + match_package_in_list(step["packages"], data) + log.info("Found matching package(s) in discover self") + + +async def handle_discover_content_type(step): + validate_keys(step, ["api", "content-type", "packages"]) + + result = await api_call("GET", f"/package/{step['content-type']}") + + if result.status != 200: + raise RegressionFailure( + f"Couldn't find package in discover {step['content-type']}; status_code={result.status}" + ) + + data = await result.json() + match_package_in_list(step["packages"], data) + log.info(f"Found matching package(s) dicover {step['content-type']}") + + +async def handle_discover_unique_id(step): + validate_keys(step, ["api", "content-type", "unique-id", "packages"]) + + result = await api_call("GET", f"/package/{step['content-type']}/{step['unique-id']}") + + if result.status != 200: + raise RegressionFailure( + f"Couldn't find package in discover {step['content-type']}/{step['unique-id']}; status_code={result.status}" + ) + + data = await result.json() + match_package_in_list(step["packages"], [data]) + log.info(f"Found matching package(s) dicover {step['content-type']}/{step['unique-id']}") + + +async def handle_new_start(step): + global token + + validate_keys(step, ["api"]) + + result = await api_call("POST", "/new-package", json={}, silent=True) + + if result.status != 200: + raise RegressionFailure(f"Couldn't create new package; status_code={result.status}") + + data = await result.json() + token = data["upload-token"] + log.info("Started new session") + + +async def handle_new_update(step): + fields = ["version", "name", "description", "license", "url", "tags", "dependencies", "compatibility"] + validate_keys(step, fields + ["api", "error"]) + + payload = {} + for field in fields: + if field in step: + payload[field] = step[field] + + result = await api_call("PUT", f"/new-package/{token}", json=payload) + + if result.status not in (204, 400): + raise RegressionFailure(f"Couldn't update package info; status_code={result.status}") + + if result.status == 400: + data = await result.json() + + if "error" in step: + for key, value in step["error"].items(): + if "." in key: + key, _, subkey = key.partition(".") + else: + subkey = None + + if key not in data["errors"]: + raise RegressionFailure(f"Expected error during info update not triggered: {key}:{value}") + + if isinstance(data["errors"][key], Mapping): + if subkey: + if not any(subkey in a and value in a[subkey] for a in data["errors"][key].values()): + raise RegressionFailure( + f"Expected error during info update not triggered: {key}.{subkey}:{value}" + ) + else: + if not any(value in a for a in data["errors"][key].values()): + raise RegressionFailure(f"Expected error during info update not triggered: {key}:{value}") + else: + if value not in data["errors"][key]: + raise RegressionFailure(f"Expected error during info update not triggered: {key}:{value}") + log.info("Found expected error during info update") + return + else: + raise RegressionFailure(f"Tried to info update, but there were errors: {data['errors']}") + elif "error" in step: + raise RegressionFailure(f"Expected error during info update not triggered: {step['error']}") + + log.info(f"Package info updated with {payload}") + + +async def handle_new_info(step): + fields = [ + "version", + "name", + "description", + "url", + "tags", + "license", + "md5sum-partial", + "content-type", + "unique-id", + "dependencies", + "compatibility", + "error", + ] + validate_keys(step, fields + ["api"]) + + result = await api_call("GET", f"/new-package/{token}") + + if result.status != 200: + raise RegressionFailure(f"Couldn't get package info; status_code={result.status}") + + data = await result.json() + + for field in fields: + if field not in step: + continue + + if field == "error": + dfield = f"{field}s" + if not step[field]: + if data[dfield]: + raise RegressionFailure( + f"Expeced entry '{dfield}' to be empty, but it is not; found: '{data[dfield]}'" + ) + elif step[field] not in data[dfield]: + raise RegressionFailure( + f"Entry in '{dfield}' is not there; found: '{data[dfield]}', expected at least '{step[field]}'" + ) + elif field not in data: + raise RegressionFailure(f"Field '{field}' is not set; expected '{step[field]}''") + elif data[field] != step[field]: + raise RegressionFailure(f"Field '{field}' is different; found: '{data[field]}', expected '{step[field]}'") + + log.info("Package info is as expected") + + +async def handle_new_publish(step): + validate_keys(step, ["api", "error"]) + + result = await api_call("POST", f"/new-package/{token}/publish", json={}) + + if result.status not in (201, 400): + raise RegressionFailure(f"Couldn't publish package; status_code={result.status}") + + data = await result.json() + + if "error" in step: + if not data["errors"]: + raise RegressionFailure("Expected error during publish, but none found") + if step["error"] not in data["errors"]: + raise RegressionFailure(f"Expected error during publish not triggered: {step['error']}") + log.info("Found expected error during publishing") + return + + if data["errors"]: + raise RegressionFailure(f"Tried to publish, but there were errors: {data['errors']}") + log.info("Published") + + +async def handle_new_delete_file(step): + validate_keys(step, ["filename", "uuid"]) + + if "uuid" in step: + result = await api_call("DELETE", f"/new-package/{token}/{step['uuid']}") + + if result.status != 404: + raise RegressionFailure(f"Could delete file, but that should be impossible") + + log.info(f"Failed to remove file (expected)") + return + + result = await api_call("GET", f"/new-package/{token}") + + if result.status != 200: + raise RegressionFailure(f"Couldn't get package info; status_code={result.status}") + + data = await result.json() + + for file_info in data["files"]: + if file_info["filename"] == step["filename"]: + result = await api_call("DELETE", f"/new-package/{token}/{file_info['uuid']}") + + if result.status != 204: + raise RegressionFailure(f"Couldn't delete file; status_code={result.status}") + + log.info(f"File with name {step['filename']} deleted") + break + else: + raise RegressionFailure(f"No filename {step['filename']} found to delete") + + +api_mapping = { + "user/login": handle_user_login, + "user/loguot": handle_user_logout, + "discover/self": handle_discover_self, + "discover/content-type": handle_discover_content_type, + "discover/unique-id": handle_discover_unique_id, + "new-package/start": handle_new_start, + "new-package/update": handle_new_update, + "new-package/info": handle_new_info, + "new-package/publish": handle_new_publish, + "new-package/delete-file": handle_new_delete_file, +} + + +async def handle_api(step): + func = api_mapping.get(step["api"]) + if not func: + raise DefinitionFailure(f"Unknown API {step['api']}") + + await func(step) + + +async def handle_file_upload(step): + validate_keys(step, ["file-upload", "name"]) + + filename = step["file-upload"] + fullpath = "/".join(current_regression.split("/")[:-1]) + fullpath = f"{fullpath}/{filename}" + + if "name" in step: + filename = step["name"] + + tus = TusClient("http://127.0.0.1:1080/new-package/tus/") + tus.set_headers({"Upload-Token": token}) + tus.set_headers({"Authorization": auth_headers["Authorization"]}) + try: + uploader = tus.uploader(fullpath, chunk_size=5 * 1024 * 1024, metadata={"filename": filename}) + except Exception: + raise RegressionFailure(f"Couldn't upload file '{filename}'") + uploader.upload() + + +async def set_death_signal(): + PR_SET_PDEATHSIG = 1 + + libc = ctypes.CDLL(find_library("c")) + libc.prctl(PR_SET_PDEATHSIG, signal.SIGTERM, 0, 0, 0) + + +async def _run_api(use_coverage): + global python_proc + + os.environ["PYTHONPATH"] = os.getcwd() + os.environ["PYTHONUNBUFFERED"] = "1" + + with TemporaryDirectory(prefix="ottd-api") as folder: + os.chdir(folder) + + if use_coverage: + command = ["coverage", "run", "--source", "bananas_api"] + else: + command = ["python"] + + command.extend( + [ + "-m", + "bananas_api", + "--web-port", + "8080", + "--storage", + "local", + "--index", + "local", + "--user", + "developer", + "--commit-graceperiod", + "1", + "--cleanup-graceperiod", + "5", + ] + ) + python_proc = await asyncio.create_subprocess_exec( + command[0], *command[1:], stdout=asyncio.subprocess.PIPE, preexec_fn=set_death_signal, + ) + os.chdir(os.environ["PYTHONPATH"]) + + await python_proc.stdout.readline() + startup_event.set() + await python_proc.wait() + + +step_mapping = { + "api": handle_api, + "file-upload": handle_file_upload, +} + + +async def _handle_file(data): + if "steps" not in data: + raise DefinitionFailure("Invalid regression file; no 'steps' defined.") + + for step in data["steps"]: + for key in step_mapping: + if key in step: + func = step_mapping[key] + break + else: + raise DefinitionFailure(f"Unknown step: {step}") + + await func(step) + + if "Authorization" in auth_headers: + await handle_user_logout({}) + + +async def _handle_files(filenames): + global current_regression, session + + await startup_event.wait() + session = aiohttp.ClientSession() + + failed = False + + for filename in filenames: + current_regression = filename + + try: + with open(filename, "r") as f: + data = yaml.safe_load(f) + + await _handle_file(data) + log.success("Regression test passed") + except RegressionFailure as e: + log.critical(e.args[0]) + failed = True + except Exception: + log.exception("Internal regression error") + return True + + return failed + + +class RegressionFilter(logging.Filter): + @classmethod + def install(cls, handler): + handler.addFilter(cls()) + + def filter(self, record): + record.regression = "/".join(current_regression.split("/")[1:]) + return 1 + + +@click.command(context_settings=CONTEXT_SETTINGS) +@click.argument("regression-file", type=click.Path(exists=True, dir_okay=False), nargs=-1) +@click.option("--coverage", help="Run subprocess via coverage", is_flag=True) +def main(regression_file, coverage): + max_len = 0 + for filename in regression_file: + cur_len = len("/".join(filename.split("/")[1:])) + if cur_len > max_len: + max_len = cur_len + + coloredlogs.install( + fmt="%(asctime)s [%(regression)-" + str(max_len) + "s] %(levelname)-8s %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=logging.INFO, + ) + for handler in logging.getLogger().handlers: + handler.addFilter(RegressionFilter()) + + loop = asyncio.get_event_loop() + loop.create_task(_run_api(coverage)) + failed = loop.run_until_complete(_handle_files(regression_file)) + python_proc.terminate() + + if failed: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/regression_runner/requirements.base b/regression_runner/requirements.base new file mode 100644 index 0000000..433ea1e --- /dev/null +++ b/regression_runner/requirements.base @@ -0,0 +1,6 @@ +aiohttp +click +coloredlogs +PyYAML +tuspy +verboselogs diff --git a/regression_runner/requirements.txt b/regression_runner/requirements.txt new file mode 100644 index 0000000..57f4f80 --- /dev/null +++ b/regression_runner/requirements.txt @@ -0,0 +1,19 @@ +aiohttp==3.6.2 +async-timeout==3.0.1 +attrs==19.3.0 +certifi==2019.11.28 +chardet==3.0.4 +click==7.1.1 +coloredlogs==14.0 +future==0.18.2 +humanfriendly==8.1 +idna==2.9 +multidict==4.7.5 +PyYAML==5.3.1 +requests==2.23.0 +six==1.14.0 +tinydb==3.15.2 +tuspy==0.2.4 +urllib3==1.25.8 +verboselogs==1.7 +yarl==1.4.2