db.go (7404B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package testrig 19 20 import ( 21 "context" 22 "os" 23 "strconv" 24 25 "github.com/superseriousbusiness/gotosocial/internal/config" 26 "github.com/superseriousbusiness/gotosocial/internal/db" 27 "github.com/superseriousbusiness/gotosocial/internal/db/bundb" 28 "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 29 "github.com/superseriousbusiness/gotosocial/internal/log" 30 "github.com/superseriousbusiness/gotosocial/internal/state" 31 ) 32 33 var testModels = []interface{}{ 34 >smodel.Account{}, 35 >smodel.AccountToEmoji{}, 36 >smodel.Application{}, 37 >smodel.Block{}, 38 >smodel.DomainBlock{}, 39 >smodel.EmailDomainBlock{}, 40 >smodel.Follow{}, 41 >smodel.FollowRequest{}, 42 >smodel.List{}, 43 >smodel.ListEntry{}, 44 >smodel.MediaAttachment{}, 45 >smodel.Mention{}, 46 >smodel.Status{}, 47 >smodel.StatusToEmoji{}, 48 >smodel.StatusToTag{}, 49 >smodel.StatusFave{}, 50 >smodel.StatusBookmark{}, 51 >smodel.StatusMute{}, 52 >smodel.Tag{}, 53 >smodel.User{}, 54 >smodel.Emoji{}, 55 >smodel.Instance{}, 56 >smodel.Notification{}, 57 >smodel.RouterSession{}, 58 >smodel.Token{}, 59 >smodel.Client{}, 60 >smodel.EmojiCategory{}, 61 >smodel.Tombstone{}, 62 >smodel.Report{}, 63 } 64 65 // NewTestDB returns a new initialized, empty database for testing. 66 // 67 // If the environment variable GTS_DB_ADDRESS is set, it will take that 68 // value as the database address instead. 69 // 70 // If the environment variable GTS_DB_TYPE is set, it will take that 71 // value as the database type instead. 72 // 73 // If the environment variable GTS_DB_PORT is set, it will take that 74 // value as the port instead. 75 func NewTestDB(state *state.State) db.DB { 76 if alternateAddress := os.Getenv("GTS_DB_ADDRESS"); alternateAddress != "" { 77 config.SetDbAddress(alternateAddress) 78 } 79 80 if alternateDBType := os.Getenv("GTS_DB_TYPE"); alternateDBType != "" { 81 config.SetDbType(alternateDBType) 82 } 83 84 if alternateDBPort := os.Getenv("GTS_DB_PORT"); alternateDBPort != "" { 85 port, err := strconv.ParseUint(alternateDBPort, 10, 16) 86 if err != nil { 87 panic(err) 88 } 89 config.SetDbPort(int(port)) 90 } 91 92 state.Caches.Init() 93 94 testDB, err := bundb.NewBunDBService(context.Background(), state) 95 if err != nil { 96 log.Panic(nil, err) 97 } 98 99 state.DB = testDB 100 101 return testDB 102 } 103 104 // CreateTestTables creates prerequisite test tables in the database, but doesn't populate them. 105 func CreateTestTables(db db.DB) { 106 ctx := context.Background() 107 for _, m := range testModels { 108 if err := db.CreateTable(ctx, m); err != nil { 109 log.Panicf(nil, "error creating table for %+v: %s", m, err) 110 } 111 } 112 } 113 114 // StandardDBSetup populates a given db with all the necessary tables/models for perfoming tests. 115 // 116 // The accounts parameter is provided in case the db should be populated with a certain set of accounts. 117 // If accounts is nil, then the standard test accounts will be used. 118 // 119 // When testing http signatures, you should pass into this function the same accounts map that you generated 120 // signatures with, otherwise this function will randomly generate new keys for accounts and signature 121 // verification will fail. 122 func StandardDBSetup(db db.DB, accounts map[string]*gtsmodel.Account) { 123 if db == nil { 124 log.Panic(nil, "db setup: db was nil") 125 } 126 127 CreateTestTables(db) 128 129 ctx := context.Background() 130 131 for _, v := range NewTestTokens() { 132 if err := db.Put(ctx, v); err != nil { 133 log.Panic(nil, err) 134 } 135 } 136 137 for _, v := range NewTestClients() { 138 if err := db.Put(ctx, v); err != nil { 139 log.Panic(nil, err) 140 } 141 } 142 143 for _, v := range NewTestApplications() { 144 if err := db.Put(ctx, v); err != nil { 145 log.Panic(nil, err) 146 } 147 } 148 149 for _, v := range NewTestBlocks() { 150 if err := db.Put(ctx, v); err != nil { 151 log.Panic(nil, err) 152 } 153 } 154 155 for _, v := range NewTestReports() { 156 if err := db.Put(ctx, v); err != nil { 157 log.Panic(nil, err) 158 } 159 } 160 161 for _, v := range NewTestDomainBlocks() { 162 if err := db.Put(ctx, v); err != nil { 163 log.Panic(nil, err) 164 } 165 } 166 167 for _, v := range NewTestInstances() { 168 if err := db.Put(ctx, v); err != nil { 169 log.Panic(nil, err) 170 } 171 } 172 173 for _, v := range NewTestUsers() { 174 if err := db.Put(ctx, v); err != nil { 175 log.Panic(nil, err) 176 } 177 } 178 179 if accounts == nil { 180 for _, v := range NewTestAccounts() { 181 if err := db.Put(ctx, v); err != nil { 182 log.Panic(nil, err) 183 } 184 } 185 } else { 186 for _, v := range accounts { 187 if err := db.Put(ctx, v); err != nil { 188 log.Panic(nil, err) 189 } 190 } 191 } 192 193 for _, v := range NewTestAttachments() { 194 if err := db.Put(ctx, v); err != nil { 195 log.Panic(nil, err) 196 } 197 } 198 199 for _, v := range NewTestStatuses() { 200 if err := db.Put(ctx, v); err != nil { 201 log.Panic(nil, err) 202 } 203 } 204 205 for _, v := range NewTestEmojis() { 206 if err := db.Put(ctx, v); err != nil { 207 log.Panic(nil, err) 208 } 209 } 210 211 for _, v := range NewTestEmojiCategories() { 212 if err := db.Put(ctx, v); err != nil { 213 log.Panic(nil, err) 214 } 215 } 216 217 for _, v := range NewTestStatusToEmojis() { 218 if err := db.Put(ctx, v); err != nil { 219 log.Panic(nil, err) 220 } 221 } 222 223 for _, v := range NewTestTags() { 224 if err := db.Put(ctx, v); err != nil { 225 log.Panic(nil, err) 226 } 227 } 228 229 for _, v := range NewTestStatusToTags() { 230 if err := db.Put(ctx, v); err != nil { 231 log.Panic(nil, err) 232 } 233 } 234 235 for _, v := range NewTestMentions() { 236 if err := db.Put(ctx, v); err != nil { 237 log.Panic(nil, err) 238 } 239 } 240 241 for _, v := range NewTestFaves() { 242 if err := db.Put(ctx, v); err != nil { 243 log.Panic(nil, err) 244 } 245 } 246 247 for _, v := range NewTestFollows() { 248 if err := db.Put(ctx, v); err != nil { 249 log.Panic(nil, err) 250 } 251 } 252 253 for _, v := range NewTestLists() { 254 if err := db.Put(ctx, v); err != nil { 255 log.Panic(nil, err) 256 } 257 } 258 259 for _, v := range NewTestListEntries() { 260 if err := db.Put(ctx, v); err != nil { 261 log.Panic(nil, err) 262 } 263 } 264 265 for _, v := range NewTestNotifications() { 266 if err := db.Put(ctx, v); err != nil { 267 log.Panic(nil, err) 268 } 269 } 270 271 for _, v := range NewTestTombstones() { 272 if err := db.Put(ctx, v); err != nil { 273 log.Panic(nil, err) 274 } 275 } 276 277 for _, v := range NewTestBookmarks() { 278 if err := db.Put(ctx, v); err != nil { 279 log.Panic(nil, err) 280 } 281 } 282 283 if err := db.CreateInstanceAccount(ctx); err != nil { 284 log.Panic(nil, err) 285 } 286 287 if err := db.CreateInstanceInstance(ctx); err != nil { 288 log.Panic(nil, err) 289 } 290 291 log.Debug(nil, "testing db setup complete") 292 } 293 294 // StandardDBTeardown drops all the standard testing tables/models from the database to ensure it's clean for the next test. 295 func StandardDBTeardown(db db.DB) { 296 ctx := context.Background() 297 if db == nil { 298 log.Panic(nil, "db was nil") 299 } 300 for _, m := range testModels { 301 if err := db.DropTable(ctx, m); err != nil { 302 log.Panic(nil, err) 303 } 304 } 305 }