From 0a7167eac0746fb3e423a95603caa1e7ad46d9f1 Mon Sep 17 00:00:00 2001 From: smail Date: Tue, 29 Sep 2026 22:54:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E5=88=86=E5=8C=BA=E9=85=8D=E7=BD=AE=E4=BB=A3=E6=AC=A1=E5=90=8C?= =?UTF-8?q?=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同步初始化候选配置的分区 generation,避免数据库设置提交被分区代次校验拒绝,并补充回归测试。 --- .../config/partitioned_compatibility_test.go | 40 +++++++++++++++++++ backend/config/setup_writer.go | 1 + 2 files changed, 41 insertions(+) diff --git a/backend/config/partitioned_compatibility_test.go b/backend/config/partitioned_compatibility_test.go index b5f6f23b..5b5395d4 100644 --- a/backend/config/partitioned_compatibility_test.go +++ b/backend/config/partitioned_compatibility_test.go @@ -44,6 +44,46 @@ func TestPartitionedDatabaseConnectionPreservesMigrationTimezone(t *testing.T) { } } +func TestSetupRuntimeFromConfigSynchronizesSectionGeneration(t *testing.T) { + root := t.TempDir() + oldRoot := ROOT_PATH + ROOT_PATH = root + t.Cleanup(func() { ROOT_PATH = oldRoot }) + + current := validRuntimeConfig() + cfg := &Config{ + SetupState: SetupStateBootstrap, + DbType: DBTypeSQLite, + DbDSN: "smail.db", + Domain: "mail.example.com", + Domains: []string{"mail.example.com"}, + WebDomain: "mail.example.com", + SSLType: "0", + HttpsEnabled: 1, + HttpPort: 80, + HttpsPort: 443, + } + candidate, err := setupRuntimeFromConfig(current, cfg) + if err != nil { + t.Fatal(err) + } + if candidate.Generation != current.Generation+1 { + t.Fatalf("candidate generation = %d, want %d", candidate.Generation, current.Generation+1) + } + for section, generation := range map[Section]uint64{ + SectionSMTP: candidate.SMTP.Meta.Generation, + SectionEmail: candidate.Email.Meta.Generation, + SectionSSL: candidate.SSL.Meta.Generation, + SectionPlugins: candidate.Plugins.Meta.Generation, + } { + if generation != candidate.Generation { + t.Fatalf("%s generation = %d, want %d", section, generation, candidate.Generation) + } + if candidate.Root.Sections[section].Generation != candidate.Generation { + t.Fatalf("%s reference generation = %d, want %d", section, candidate.Root.Sections[section].Generation, candidate.Generation) + } + } +} func TestPartitionedCompatibilityStartupAndWriteProtection(t *testing.T) { root := t.TempDir() oldRoot, oldArgs, oldDevelopment := ROOT_PATH, os.Args, DevelopmentMode diff --git a/backend/config/setup_writer.go b/backend/config/setup_writer.go index afedecb8..29fc6269 100644 --- a/backend/config/setup_writer.go +++ b/backend/config/setup_writer.go @@ -135,6 +135,7 @@ func setupRuntimeFromConfig(current RuntimeConfig, cfg *Config) (RuntimeConfig, candidate.Email.Policy.ExternalRecoveryEnabled = cfg.ExternalRecoveryEnabled candidate.SSL.TLS = ssl candidate.Root.UpdatedAt = time.Now().UTC() + setCandidateGeneration(&candidate, candidate.Generation) return candidate, nil }