| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | package core_test | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2024-11-05 01:03:33 +08:00
										 |  |  | 	"database/sql" | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 	"log/slog" | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	"os" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	_ "unsafe" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-05 01:03:33 +08:00
										 |  |  | 	"github.com/pocketbase/dbx" | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	"github.com/pocketbase/pocketbase/core" | 
					
						
							|  |  |  | 	"github.com/pocketbase/pocketbase/tests" | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 	"github.com/pocketbase/pocketbase/tools/logger" | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	"github.com/pocketbase/pocketbase/tools/mailer" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestNewBaseApp(t *testing.T) { | 
					
						
							|  |  |  | 	const testDataDir = "./pb_base_app_test_data_dir/" | 
					
						
							|  |  |  | 	defer os.RemoveAll(testDataDir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	app := core.NewBaseApp(core.BaseAppConfig{ | 
					
						
							| 
									
										
										
										
											2022-12-15 22:42:35 +08:00
										 |  |  | 		DataDir:       testDataDir, | 
					
						
							|  |  |  | 		EncryptionEnv: "test_env", | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 		IsDev:         true, | 
					
						
							| 
									
										
										
										
											2022-12-15 22:42:35 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	if app.DataDir() != testDataDir { | 
					
						
							|  |  |  | 		t.Fatalf("expected DataDir %q, got %q", testDataDir, app.DataDir()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if app.EncryptionEnv() != "test_env" { | 
					
						
							|  |  |  | 		t.Fatalf("expected EncryptionEnv test_env, got %q", app.EncryptionEnv()) | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	if !app.IsDev() { | 
					
						
							|  |  |  | 		t.Fatalf("expected IsDev true, got %v", app.IsDev()) | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	if app.Store() == nil { | 
					
						
							|  |  |  | 		t.Fatal("expected Store to be set, got nil") | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	if app.Settings() == nil { | 
					
						
							|  |  |  | 		t.Fatal("expected Settings to be set, got nil") | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	if app.SubscriptionsBroker() == nil { | 
					
						
							|  |  |  | 		t.Fatal("expected SubscriptionsBroker to be set, got nil") | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	if app.Cron() == nil { | 
					
						
							|  |  |  | 		t.Fatal("expected Cron to be set, got nil") | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestBaseAppBootstrap(t *testing.T) { | 
					
						
							|  |  |  | 	const testDataDir = "./pb_base_app_test_data_dir/" | 
					
						
							|  |  |  | 	defer os.RemoveAll(testDataDir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	app := core.NewBaseApp(core.BaseAppConfig{ | 
					
						
							|  |  |  | 		DataDir: testDataDir, | 
					
						
							| 
									
										
										
										
											2022-12-15 22:42:35 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	defer app.ResetBootstrapState() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 05:20:23 +08:00
										 |  |  | 	if app.IsBootstrapped() { | 
					
						
							|  |  |  | 		t.Fatal("Didn't expect the application to be bootstrapped.") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	if err := app.Bootstrap(); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 05:20:23 +08:00
										 |  |  | 	if !app.IsBootstrapped() { | 
					
						
							|  |  |  | 		t.Fatal("Expected the application to be bootstrapped.") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	if stat, err := os.Stat(testDataDir); err != nil || !stat.IsDir() { | 
					
						
							|  |  |  | 		t.Fatal("Expected test data directory to be created.") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	type nilCheck struct { | 
					
						
							|  |  |  | 		name      string | 
					
						
							|  |  |  | 		value     any | 
					
						
							|  |  |  | 		expectNil bool | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	runNilChecks := func(checks []nilCheck) { | 
					
						
							|  |  |  | 		for _, check := range checks { | 
					
						
							|  |  |  | 			t.Run(check.name, func(t *testing.T) { | 
					
						
							|  |  |  | 				isNil := check.value == nil | 
					
						
							|  |  |  | 				if isNil != check.expectNil { | 
					
						
							|  |  |  | 					t.Fatalf("Expected isNil %v, got %v", check.expectNil, isNil) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	nilChecksBeforeReset := []nilCheck{ | 
					
						
							|  |  |  | 		{"[before] concurrentDB", app.DB(), false}, | 
					
						
							|  |  |  | 		{"[before] nonconcurrentDB", app.NonconcurrentDB(), false}, | 
					
						
							|  |  |  | 		{"[before] auxConcurrentDB", app.AuxDB(), false}, | 
					
						
							|  |  |  | 		{"[before] auxNonconcurrentDB", app.AuxNonconcurrentDB(), false}, | 
					
						
							|  |  |  | 		{"[before] settings", app.Settings(), false}, | 
					
						
							|  |  |  | 		{"[before] logger", app.Logger(), false}, | 
					
						
							|  |  |  | 		{"[before] cached collections", app.Store().Get(core.StoreKeyCachedCollections), false}, | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	runNilChecks(nilChecksBeforeReset) | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	// reset
 | 
					
						
							|  |  |  | 	if err := app.ResetBootstrapState(); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	nilChecksAfterReset := []nilCheck{ | 
					
						
							|  |  |  | 		{"[after] concurrentDB", app.DB(), true}, | 
					
						
							|  |  |  | 		{"[after] nonconcurrentDB", app.NonconcurrentDB(), true}, | 
					
						
							|  |  |  | 		{"[after] auxConcurrentDB", app.AuxDB(), true}, | 
					
						
							|  |  |  | 		{"[after] auxNonconcurrentDB", app.AuxNonconcurrentDB(), true}, | 
					
						
							|  |  |  | 		{"[after] settings", app.Settings(), false}, | 
					
						
							|  |  |  | 		{"[after] logger", app.Logger(), false}, | 
					
						
							|  |  |  | 		{"[after] cached collections", app.Store().Get(core.StoreKeyCachedCollections), false}, | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	runNilChecks(nilChecksAfterReset) | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | func TestNewBaseAppIsTransactional(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	const testDataDir = "./pb_base_app_test_data_dir/" | 
					
						
							|  |  |  | 	defer os.RemoveAll(testDataDir) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	app := core.NewBaseApp(core.BaseAppConfig{ | 
					
						
							|  |  |  | 		DataDir: testDataDir, | 
					
						
							| 
									
										
										
										
											2022-12-15 22:42:35 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	defer app.ResetBootstrapState() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := app.Bootstrap(); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	if app.IsTransactional() { | 
					
						
							|  |  |  | 		t.Fatalf("Didn't expect the app to be transactional") | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	app.RunInTransaction(func(txApp core.App) error { | 
					
						
							|  |  |  | 		if !txApp.IsTransactional() { | 
					
						
							|  |  |  | 			t.Fatalf("Expected the app to be transactional") | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestBaseAppNewMailClient(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	const testDataDir = "./pb_base_app_test_data_dir/" | 
					
						
							|  |  |  | 	defer os.RemoveAll(testDataDir) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	app := core.NewBaseApp(core.BaseAppConfig{ | 
					
						
							|  |  |  | 		DataDir:       testDataDir, | 
					
						
							|  |  |  | 		EncryptionEnv: "pb_test_env", | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	defer app.ResetBootstrapState() | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	client1 := app.NewMailClient() | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	m1, ok := client1.(*mailer.Sendmail) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatalf("Expected mailer.Sendmail instance, got %v", m1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if m1.OnSend() == nil || m1.OnSend().Length() == 0 { | 
					
						
							|  |  |  | 		t.Fatal("Expected OnSend hook to be registered") | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	app.Settings().SMTP.Enabled = true | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	client2 := app.NewMailClient() | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	m2, ok := client2.(*mailer.SMTPClient) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		t.Fatalf("Expected mailer.SMTPClient instance, got %v", m2) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if m2.OnSend() == nil || m2.OnSend().Length() == 0 { | 
					
						
							|  |  |  | 		t.Fatal("Expected OnSend hook to be registered") | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestBaseAppNewFilesystem(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	const testDataDir = "./pb_base_app_test_data_dir/" | 
					
						
							|  |  |  | 	defer os.RemoveAll(testDataDir) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	app := core.NewBaseApp(core.BaseAppConfig{ | 
					
						
							|  |  |  | 		DataDir: testDataDir, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	defer app.ResetBootstrapState() | 
					
						
							| 
									
										
										
										
											2022-07-07 05:19:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// local
 | 
					
						
							|  |  |  | 	local, localErr := app.NewFilesystem() | 
					
						
							|  |  |  | 	if localErr != nil { | 
					
						
							|  |  |  | 		t.Fatal(localErr) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if local == nil { | 
					
						
							|  |  |  | 		t.Fatal("Expected local filesystem instance, got nil") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// misconfigured s3
 | 
					
						
							|  |  |  | 	app.Settings().S3.Enabled = true | 
					
						
							|  |  |  | 	s3, s3Err := app.NewFilesystem() | 
					
						
							|  |  |  | 	if s3Err == nil { | 
					
						
							|  |  |  | 		t.Fatal("Expected S3 error, got nil") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if s3 != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Expected nil s3 filesystem, got %v", s3) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-05-09 02:52:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestBaseAppNewBackupsFilesystem(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	const testDataDir = "./pb_base_app_test_data_dir/" | 
					
						
							|  |  |  | 	defer os.RemoveAll(testDataDir) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	app := core.NewBaseApp(core.BaseAppConfig{ | 
					
						
							|  |  |  | 		DataDir: testDataDir, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	defer app.ResetBootstrapState() | 
					
						
							| 
									
										
										
										
											2023-05-09 02:52:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// local
 | 
					
						
							|  |  |  | 	local, localErr := app.NewBackupsFilesystem() | 
					
						
							|  |  |  | 	if localErr != nil { | 
					
						
							|  |  |  | 		t.Fatal(localErr) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if local == nil { | 
					
						
							|  |  |  | 		t.Fatal("Expected local backups filesystem instance, got nil") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// misconfigured s3
 | 
					
						
							|  |  |  | 	app.Settings().Backups.S3.Enabled = true | 
					
						
							|  |  |  | 	s3, s3Err := app.NewBackupsFilesystem() | 
					
						
							|  |  |  | 	if s3Err == nil { | 
					
						
							|  |  |  | 		t.Fatal("Expected S3 error, got nil") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if s3 != nil { | 
					
						
							|  |  |  | 		t.Fatalf("Expected nil s3 backups filesystem, got %v", s3) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestBaseAppLoggerWrites(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	t.Parallel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	app, _ := tests.NewTestApp() | 
					
						
							|  |  |  | 	defer app.Cleanup() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// reset
 | 
					
						
							|  |  |  | 	if err := app.DeleteOldLogs(time.Now()); err != nil { | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 	const logsThreshold = 200 | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 	totalLogs := func(app core.App, t *testing.T) int { | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 		var total int | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 		err := app.LogQuery().Select("count(*)").Row(&total) | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Failed to fetch total logs: %v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 		return total | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-12-10 18:30:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 	t.Run("disabled logs retention", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-12-10 18:30:55 +08:00
										 |  |  | 		app.Settings().Logs.MaxDays = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 		for i := 0; i < logsThreshold+1; i++ { | 
					
						
							| 
									
										
										
										
											2023-12-10 18:30:55 +08:00
										 |  |  | 			app.Logger().Error("test") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if total := totalLogs(app, t); total != 0 { | 
					
						
							|  |  |  | 			t.Fatalf("Expected no logs, got %d", total) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2023-12-10 18:30:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 	t.Run("test batch logs writes", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-12-10 18:30:55 +08:00
										 |  |  | 		app.Settings().Logs.MaxDays = 1 | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 		for i := 0; i < logsThreshold-1; i++ { | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 			app.Logger().Error("test") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if total := totalLogs(app, t); total != 0 { | 
					
						
							| 
									
										
										
										
											2023-12-10 18:30:55 +08:00
										 |  |  | 			t.Fatalf("Expected no logs, got %d", total) | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// should trigger batch write
 | 
					
						
							|  |  |  | 		app.Logger().Error("test") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// should be added for the next batch write
 | 
					
						
							|  |  |  | 		app.Logger().Error("test") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 		if total := totalLogs(app, t); total != logsThreshold { | 
					
						
							|  |  |  | 			t.Fatalf("Expected %d logs, got %d", logsThreshold, total) | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// wait for ~3 secs to check the timer trigger
 | 
					
						
							|  |  |  | 		time.Sleep(3200 * time.Millisecond) | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 		if total := totalLogs(app, t); total != logsThreshold+1 { | 
					
						
							|  |  |  | 			t.Fatalf("Expected %d logs, got %d", logsThreshold+1, total) | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-07-06 19:03:10 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2023-11-26 19:33:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | func TestBaseAppRefreshSettingsLoggerMinLevelEnabled(t *testing.T) { | 
					
						
							|  |  |  | 	scenarios := []struct { | 
					
						
							|  |  |  | 		name  string | 
					
						
							|  |  |  | 		isDev bool | 
					
						
							|  |  |  | 		level int | 
					
						
							|  |  |  | 		// level->enabled map
 | 
					
						
							|  |  |  | 		expectations map[int]bool | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"dev mode", | 
					
						
							|  |  |  | 			true, | 
					
						
							|  |  |  | 			4, | 
					
						
							|  |  |  | 			map[int]bool{ | 
					
						
							|  |  |  | 				3: true, | 
					
						
							|  |  |  | 				4: true, | 
					
						
							|  |  |  | 				5: true, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			"nondev mode", | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 			4, | 
					
						
							|  |  |  | 			map[int]bool{ | 
					
						
							|  |  |  | 				3: false, | 
					
						
							|  |  |  | 				4: true, | 
					
						
							|  |  |  | 				5: true, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, s := range scenarios { | 
					
						
							|  |  |  | 		t.Run(s.name, func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 			const testDataDir = "./pb_base_app_test_data_dir/" | 
					
						
							|  |  |  | 			defer os.RemoveAll(testDataDir) | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 			app := core.NewBaseApp(core.BaseAppConfig{ | 
					
						
							|  |  |  | 				DataDir: testDataDir, | 
					
						
							|  |  |  | 				IsDev:   s.isDev, | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 			defer app.ResetBootstrapState() | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 			if err := app.Bootstrap(); err != nil { | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 				t.Fatal(err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-05 01:03:33 +08:00
										 |  |  | 			// silence query logs
 | 
					
						
							|  |  |  | 			app.DB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} | 
					
						
							|  |  |  | 			app.DB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} | 
					
						
							|  |  |  | 			app.NonconcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {} | 
					
						
							|  |  |  | 			app.NonconcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 			handler, ok := app.Logger().Handler().(*logger.BatchHandler) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				t.Fatalf("Expected BatchHandler, got %v", app.Logger().Handler()) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 			app.Settings().Logs.MinLevel = s.level | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 			if err := app.Save(app.Settings()); err != nil { | 
					
						
							|  |  |  | 				t.Fatalf("Failed to save settings: %v", err) | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-09-30 00:23:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			for level, enabled := range s.expectations { | 
					
						
							|  |  |  | 				if v := handler.Enabled(context.Background(), slog.Level(level)); v != enabled { | 
					
						
							|  |  |  | 					t.Fatalf("Expected level %d Enabled() to be %v, got %v", level, enabled, v) | 
					
						
							| 
									
										
										
										
											2023-12-16 21:41:12 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |