1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2025-09-30 19:22:08 +00:00
forgejo/models
Gusted be274b43a6 chore: add SQL fault injector testing (#9314)
TL;DR we can test if transactions are actually working.

Forgejo has many helper functions to test various aspects of the database state, however one aspect it is not able to test is transactions. As this would require that some random SQL query fails to indeed observe that the whole transaction is being rollbacked.

So how do we make a random SQL query fail? Via a fault injector hook, which is always added to xorm (during unittest) and can be enabled on demand to say after how many SQL queries it should start returning a error (fault injecting).

This allows a test to do the following: after two SQL queries lets call it a day and then execute the function that starts a transaction and does a few SQL query. It can then observe that indeed the function was fault injected (`ErrFaultInjected` is returned) and after querying the database it can observe that nothing was changed and thus can conclude the transaction was rollbacked.

---

To demonstrate how the fault injector test helper can be used, lets add a test to a function I really wanted to test but couldn't because the fault injector didn't exist. `NewTwoFactor` was recently made into a transaction (a8c61532d2) and although it would not be catastrophic it would be really bad if records were being inserted if for some reason setting the secret failed.

The test that's added demonstrates that the function uses a transaction and rollbacks correctly.

Weirdly enough the fault injector can be viewed as testing a specification, because it assumes nothing about how the function does it (and you could even design a function that purposely doesn't work but succeeds this test), it merely assumes there's a transaction and within that transaction some SQL queries will be done. However it also needs a certain amount of knowledge about how the function is implemented because the developer needs to tell after how many SQL queries you want to inject a fault and you want to do at a point where there's already a observable change happening in the transaction and not fault inject if the transaction only contains `SELECT` queries.

I'm sure you could design a smart fault injector that can do such guess work (although it sounds like a topic for a PhD thesis) and you could design a helper function that can then guide the fault injector to find every interesting place to do a fault injection and ensure the transaction always falls back; as a first prototype having the programmer tell after how many SQL queries a fault should be injected is sufficient for a lot of the transaction we are going to test in Forgejo.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9314
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-09-18 00:39:06 +02:00
..
actions fix: loading action logs on a task that isn't fetched yet, fails when the job is fetched (#9293) 2025-09-14 14:30:02 +02:00
activities fix: prevent user-entered text with | characters from being truncated in activity feed (#8844) 2025-08-10 19:48:46 +02:00
admin chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
asymkey feat(build): improve lint-locale-usage further (#8736) 2025-08-27 23:47:34 +02:00
auth chore: add SQL fault injector testing (#9314) 2025-09-18 00:39:06 +02:00
avatars chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
db feat: improve mysqlGetNextResourceIndex to use modern MariaDB features (#8691) 2025-08-08 01:51:55 +02:00
dbfs Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
fixtures fix: loading action logs on a task that isn't fetched yet, fails when the job is fetched (#9293) 2025-09-14 14:30:02 +02:00
forgefed Federated user activity following: Isolated model changes (#8078) 2025-06-21 12:02:58 +02:00
forgejo/semver Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
forgejo_migrations feat: add tag label to commit list view (#8759) 2025-08-06 14:47:51 +02:00
git feat: always publish the link to the commit status (#8177) 2025-06-13 12:41:34 +02:00
issues fix: ignore existence of commits for force pushes (#9262) 2025-09-12 07:27:15 +02:00
migrations feat: migrate action secrets to keying to store them more securely (#8692) 2025-07-29 01:03:36 +02:00
moderation feat(build): improve lint-locale-usage further (#8736) 2025-08-27 23:47:34 +02:00
organization fix(ui): wrong org dashboard links when switching dashboard context (#8688) 2025-08-07 14:32:55 +02:00
packages several fixes of ALT Package registry (#8475) 2025-07-10 17:12:07 +02:00
perm fix: allow Actions tokens to access repos readable by signed in users (#8889) 2025-08-18 14:40:07 +02:00
project feat(build): improve lint-locale-usage further (#8736) 2025-08-27 23:47:34 +02:00
pull fix: do not ignore automerge while a PR is checking for conflicts (#8189) 2025-06-17 10:58:07 +02:00
quota fix: quotas double counting repo size when calculating size:all (#9234) 2025-09-11 16:30:04 +02:00
repo feat: make upload URL compatible with GitHub API (#9285) 2025-09-15 15:53:35 +02:00
secret feat: migrate action secrets to keying to store them more securely (#8692) 2025-07-29 01:03:36 +02:00
shared/types chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
system Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
unit feat(build): improve lint-locale-usage further (#8736) 2025-08-27 23:47:34 +02:00
unittest chore: add SQL fault injector testing (#9314) 2025-09-18 00:39:06 +02:00
user fix: ensure GetUserByEmail only considers validated emails (#9075) 2025-08-30 13:16:03 +02:00
webhook Actions Failure, Succes, Recover Webhooks (#7508) 2025-06-03 14:29:19 +02:00
error.go fix: don't allow credentials in migrate/push mirror URL 2025-08-30 08:07:23 +02:00
main_test.go chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
org.go chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
org_team.go chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
org_team_test.go Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
org_test.go Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
repo.go chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
repo_test.go Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
repo_transfer.go chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
repo_transfer_test.go Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00