🐛 fix(driver-manager/mongodb): 恢复旧版 MongoDB 连接兼容

- 默认版本:将 MongoDB 推荐 driver-agent 切到 1.17.9
- 安装策略:v1 兼容驱动优先尝试发布资产,不再强制源码构建
- 状态提示:已安装 2.x 时提示重装以兼容 MongoDB 4.0
- 前端交互:重装驱动优先选择推荐兼容版本
- 测试覆盖:补充版本选择、下载候选和重装传参回归
This commit is contained in:
Syngnat
2026-06-12 15:18:57 +08:00
parent c3a3387ee3
commit c99cdb5d0d
5 changed files with 165 additions and 29 deletions

View File

@@ -230,4 +230,62 @@ describe('DriverManagerModal toolbar actions', () => {
vi.useRealTimers();
}
});
it('reinstalls stale MongoDB v2 drivers with the v1 compatibility default', async () => {
vi.useFakeTimers({ shouldAdvanceTime: true });
try {
vi.setSystemTime(new Date(Date.now() + 2 * 60 * 1000));
backendApp.GetDriverStatusList.mockResolvedValue({
success: true,
data: {
downloadDir: 'D:/drivers',
drivers: [
{
type: 'mongodb',
name: 'MongoDB',
builtIn: false,
pinnedVersion: '1.17.9',
installedVersion: '2.5.0',
runtimeAvailable: true,
packageInstalled: true,
connectable: true,
needsUpdate: true,
defaultDownloadUrl: 'builtin://activate/mongodb',
message: '建议重装',
},
],
},
});
backendApp.GetDriverVersionList.mockResolvedValue({
success: true,
data: {
versions: [
{ version: '2.5.0', downloadUrl: 'builtin://activate/mongodb?version=2.5.0' },
{ version: '1.17.9', downloadUrl: 'builtin://activate/mongodb', recommended: true },
],
},
});
backendApp.DownloadDriverPackage.mockResolvedValue({ success: true });
let renderer: ReactTestRenderer;
await act(async () => {
renderer = create(<DriverManagerModal open onClose={vi.fn()} />);
});
await flushPromises();
const reinstallButton = findButton(renderer!, '重装驱动');
await act(async () => {
await reinstallButton.props.onClick();
});
expect(backendApp.DownloadDriverPackage).toHaveBeenCalledWith(
'mongodb',
'1.17.9',
'builtin://activate/mongodb',
'D:/drivers',
);
} finally {
vi.useRealTimers();
}
});
});

View File

@@ -525,6 +525,8 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onOpenG
return prev;
}
const preferred =
(row.needsUpdate ? options.find((option) => option.version === row.pinnedVersion) : undefined) ||
(row.needsUpdate ? options.find((option) => option.recommended) : undefined) ||
options.find((option) => option.version === row.installedVersion) ||
options.find((option) => option.version === row.pinnedVersion) ||
options.find((option) => option.recommended) ||
@@ -712,6 +714,8 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onOpenG
}
const selectedKey = selectedVersionMap[row.type];
const selectedOption =
(row.needsUpdate ? versionOptions.find((item) => item.version === row.pinnedVersion) : undefined) ||
(row.needsUpdate ? versionOptions.find((item) => item.recommended) : undefined) ||
versionOptions.find((item) => buildVersionOptionKey(item) === selectedKey) ||
versionOptions.find((item) => item.recommended) ||
versionOptions[0];
@@ -1033,7 +1037,7 @@ const DriverManagerModal: React.FC<{ open: boolean; onClose: () => void; onOpenG
const selectedKey = selectedVersionMap[row.type];
const selectOptions = buildVersionSelectOptions(options);
const mongoHint = row.type === 'mongodb'
? '当前仅支持 MongoDB 1.17.x 和 2.x更老 1.x 暂不提供安装。'
? 'MongoDB 4.0 请使用 1.17.x 兼容驱动2.x 驱动要求 MongoDB 4.2+。'
: '';
return (
<div className="driver-manager-version-control">

View File

@@ -352,7 +352,7 @@ const builtinDriverManifestJSON = `{
"vastbase": { "engine": "go", "version": "1.11.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/vastbase" },
"opengauss": { "engine": "go", "version": "1.11.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/opengauss" },
"iris": { "engine": "go", "version": "0.2.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/iris" },
"mongodb": { "engine": "go", "version": "2.5.0", "checksumPolicy": "off", "downloadUrl": "builtin://activate/mongodb" },
"mongodb": { "engine": "go", "version": "1.17.9", "checksumPolicy": "off", "downloadUrl": "builtin://activate/mongodb" },
"tdengine": { "engine": "go", "version": "3.7.8", "checksumPolicy": "off", "downloadUrl": "builtin://activate/tdengine" },
"clickhouse": { "engine": "go", "version": "2.43.1", "checksumPolicy": "off", "downloadUrl": "builtin://activate/clickhouse" },
"elasticsearch": { "engine": "go", "version": "8.19.6", "checksumPolicy": "off", "downloadUrl": "builtin://activate/elasticsearch" }
@@ -821,7 +821,7 @@ func (a *App) GetDriverStatusList(downloadDir string, manifestURL string) connec
engine := effectiveDriverEngine(definition)
runtimeAvailable, runtimeReason := db.DriverRuntimeSupportStatus(definition.Type)
pkg, packageMetaExists := readInstalledDriverPackage(resolvedDir, definition.Type)
needsUpdate, updateReason, expectedRevision := optionalDriverAgentRevisionStatus(definition.Type, pkg, packageMetaExists)
needsUpdate, updateReason, expectedRevision := optionalDriverPackageUpdateStatus(definition, pkg, packageMetaExists)
packageInstalled := definition.BuiltIn || packageMetaExists
if runtimeAvailable && db.IsOptionalGoDriver(definition.Type) {
packageInstalled = true
@@ -2828,6 +2828,31 @@ func optionalDriverAgentRevisionStatus(driverType string, pkg installedDriverPac
return true, fmt.Sprintf("原因:%s。影响%s已安装标记%s当前需要%s", updateReason, impact, actual, expected), expected
}
func optionalDriverPackageUpdateStatus(definition driverDefinition, pkg installedDriverPackage, packageMetaExists bool) (bool, string, string) {
needsUpdate, reason, expected := optionalDriverAgentRevisionStatus(definition.Type, pkg, packageMetaExists)
if needsUpdate {
return true, reason, expected
}
if mongoDriverNeedsLegacyCompatibilityUpdate(definition, pkg, packageMetaExists) {
pinned := strings.TrimSpace(definition.PinnedVersion)
installed := strings.TrimSpace(pkg.Version)
return true, fmt.Sprintf("原因:当前推荐 MongoDB 兼容驱动版本为 %s已安装版本为 %s。影响MongoDB 2.x driver-agent 使用官方 v2 驱动,要求服务端 MongoDB 4.2+;连接 MongoDB 4.0 会出现 wire version 7 不兼容。强烈建议重装对应驱动代理", pinned, installed), expected
}
return false, "", expected
}
func mongoDriverNeedsLegacyCompatibilityUpdate(definition driverDefinition, pkg installedDriverPackage, packageMetaExists bool) bool {
if normalizeDriverType(definition.Type) != "mongodb" || !packageMetaExists {
return false
}
pinned := normalizeVersion(strings.TrimSpace(definition.PinnedVersion))
installed := normalizeVersion(strings.TrimSpace(pkg.Version))
if pinned == "" || installed == "" {
return false
}
return resolveMongoDriverMajorFromVersion(installed) == 2 && resolveMongoDriverMajorFromVersion(pinned) == 1
}
func optionalDriverAgentRevisionCurrent(driverType string, executablePath string) (string, bool, error) {
expected := strings.TrimSpace(db.OptionalDriverAgentRevision(driverType))
if expected == "" {
@@ -3967,28 +3992,8 @@ func resolveMongoDriverMajorFromVersion(version string) int {
return 2
}
func shouldForceSourceBuildForVersion(driverType string, selectedVersion string) bool {
if normalizeDriverType(driverType) != "mongodb" {
return false
}
return resolveMongoDriverMajorFromVersion(selectedVersion) == 1
}
func shouldForceSourceBuildForResolvedDownload(driverType string, selectedVersion string, downloadURL string) bool {
if !shouldForceSourceBuildForVersion(driverType, selectedVersion) {
return false
}
parsed, err := url.Parse(strings.TrimSpace(downloadURL))
if err != nil || parsed == nil {
return true
}
switch strings.ToLower(strings.TrimSpace(parsed.Scheme)) {
case "http", "https":
return false
default:
return true
}
func shouldForceSourceBuildForResolvedDownload(_ string, _ string, _ string) bool {
return false
}
func shouldPreferSourceBuildBeforeDownload(driverType string, selectedVersion string) bool {
@@ -4878,7 +4883,7 @@ func resolveOptionalDriverAgentDownloadURLs(definition driverDefinition, rawURL
appendURL(publishedURL)
}
}
if publishedURL, ok := resolveLatestPublishedDriverDownloadURL(definition); ok {
if publishedURL, ok := resolveLatestPublishedDriverDownloadURLForVersion(definition, selectedVersion); ok {
appendURL(publishedURL)
}
}
@@ -5510,6 +5515,10 @@ func fetchLatestReleaseForDriverAssets() (*githubRelease, error) {
}
func resolveLatestPublishedDriverDownloadURL(definition driverDefinition) (string, bool) {
return resolveLatestPublishedDriverDownloadURLForVersion(definition, "")
}
func resolveLatestPublishedDriverDownloadURLForVersion(definition driverDefinition, selectedVersion string) (string, bool) {
driverType := normalizeDriverType(definition.Type)
if driverType == "" {
return "", false
@@ -5542,7 +5551,7 @@ func resolveLatestPublishedDriverDownloadURL(definition driverDefinition) (strin
return "", false
}
assetNames := optionalDriverReleaseAssetNames(driverType)
assetNames := optionalDriverReleaseAssetNamesForVersion(driverType, selectedVersion)
if len(assetNames) == 0 {
return "", false
}

View File

@@ -33,6 +33,25 @@ func TestOptionalDriverAgentRevisionStatusDetectsStaleClickHouseAgent(t *testing
}
}
func TestOptionalDriverPackageUpdateStatusDetectsMongoV2WhenLegacyDefault(t *testing.T) {
definition, ok := resolveDriverDefinition("mongodb")
if !ok {
t.Fatal("expected mongodb driver definition")
}
meta := installedDriverPackage{
Version: "2.5.0",
AgentRevision: db.OptionalDriverAgentRevision("mongodb"),
}
needsUpdate, reason, _ := optionalDriverPackageUpdateStatus(definition, meta, true)
if !needsUpdate {
t.Fatal("expected installed MongoDB v2 driver to require reinstall when v1 is the compatibility default")
}
if !strings.Contains(reason, "MongoDB 4.0") || !strings.Contains(reason, "wire version 7") {
t.Fatalf("expected reason to explain MongoDB 4.0 compatibility, got %q", reason)
}
}
func TestOptionalDriverAgentRevisionCurrentRejectsStaleMetadata(t *testing.T) {
originalProbe := optionalDriverAgentMetadataProbe
t.Cleanup(func() {

View File

@@ -44,6 +44,20 @@ func TestResolveVersionedDriverOptionUsesPublishedMongoV1Release(t *testing.T) {
}
}
func TestMongoDBDefaultDriverVersionUsesLegacyCompatibleLine(t *testing.T) {
definition, ok := resolveDriverDefinition("mongodb")
if !ok {
t.Fatal("expected mongodb driver definition")
}
if definition.PinnedVersion != "1.17.9" {
t.Fatalf("expected MongoDB default driver version 1.17.9, got %q", definition.PinnedVersion)
}
if got := resolveDriverInstallVersion("", definition.DefaultDownloadURL, definition); got != "1.17.9" {
t.Fatalf("expected builtin MongoDB install to resolve version 1.17.9, got %q", got)
}
}
func TestCurrentDriverReleaseTagUsesDevLatestForDevBuild(t *testing.T) {
originalVersion := AppVersion
AppVersion = "dev-abc1234"
@@ -220,6 +234,38 @@ func TestResolveOptionalDriverAgentDownloadURLsDoesNotFallbackForHistoricalVersi
}
}
func TestResolveOptionalDriverAgentDownloadURLsUsesMongoV1AssetForCompatibleDefault(t *testing.T) {
definition, ok := resolveDriverDefinition("mongodb")
if !ok {
t.Fatal("expected mongodb driver definition")
}
originalVersion := AppVersion
AppVersion = "0.7.9"
t.Cleanup(func() {
AppVersion = originalVersion
})
assetName := mongoVersionedReleaseAssetName(1)
seedReleaseAssetSizeCache(t, "tag:v0.7.9", map[string]int64{
assetName: 24 << 20,
})
seedReleaseAssetSizeCache(t, "latest", map[string]int64{})
urls := resolveOptionalDriverAgentDownloadURLs(
definition,
"builtin://activate/mongodb",
"1.17.9",
)
want := driverReleaseDownloadURL("v0.7.9", assetName)
for _, got := range urls {
if got == want {
return
}
}
t.Fatalf("expected MongoDB v1 release asset %q in candidates, got %v", want, urls)
}
func TestResolveOptionalDriverAgentDownloadURLsSkipsBundleOnlyDamengAsset(t *testing.T) {
definition, ok := resolveDriverDefinition("dameng")
if !ok {
@@ -662,8 +708,8 @@ func TestResolveRecentDriverVersionMetasFallsBackToHistoricalTDengineMatrix(t *t
}
func TestShouldForceSourceBuildForResolvedDownload(t *testing.T) {
if !shouldForceSourceBuildForResolvedDownload("mongodb", "1.17.4", "builtin://activate/mongodb?channel=history&version=1.17.4") {
t.Fatal("expected mongodb v1 builtin install to keep source build mode")
if shouldForceSourceBuildForResolvedDownload("mongodb", "1.17.4", "builtin://activate/mongodb?channel=history&version=1.17.4") {
t.Fatal("expected mongodb v1 builtin install to try published assets before source build")
}
explicitURL := driverReleaseDownloadURL("v1.17.4", mongoVersionedReleaseAssetName(1))