Files
sub2api/backend/internal/repository/plugin_repo_integration_test.go
T

71 lines
2.5 KiB
Go

//go:build integration
package repository
import (
"context"
"errors"
"strings"
"testing"
"time"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/stretchr/testify/require"
)
func TestPluginRepositoryLifecycleIsAtomicAndOptimistic(t *testing.T) {
ctx := context.Background()
repo := &pluginRepository{db: integrationDB}
pluginKey := "local.test.repository-" + strings.ToLower(time.Now().Format("150405.000000000"))
defer func() {
_, _ = integrationDB.ExecContext(ctx, `DELETE FROM sub2api_plugin_installations WHERE plugin_key = $1`, pluginKey)
}()
manifest := service.PluginManifest{SchemaVersion: 1, ID: pluginKey, Name: "测试插件", Version: "1.0.0"}
first := &service.PluginInstallation{
PluginKey: pluginKey, Name: "测试插件", Version: "1.0.0", Manifest: manifest,
ArtifactData: []byte("first-package"), ArtifactPath: "/tmp/first.s2plugin",
InstallPath: "/tmp/first", BinaryPath: "/tmp/first/plugin",
BinarySHA256: strings.Repeat("a", 64), SignatureStatus: service.PluginSignatureTrusted,
State: service.PluginStateDisabled,
}
bindings := []service.PluginBinding{{
Capability: service.PluginCapabilityOpenAIOAuthOutbound,
Platform: service.PlatformOpenAI, AccountType: service.AccountTypeOAuth,
RolloutPercent: 100,
}}
installed, err := repo.Install(ctx, first, bindings)
require.NoError(t, err)
artifact, err := repo.GetArtifact(ctx, installed.ID)
require.NoError(t, err)
require.Equal(t, first.ArtifactData, artifact)
require.NoError(t, repo.BeginEnable(ctx, installed.ID, first.BinarySHA256, service.PluginStateDisabled))
bindings[0].Enabled = true
now := time.Now()
require.NoError(t, repo.UpdateBindingsAndState(
ctx, installed.ID, bindings, service.PluginStateEnabled, "", &now,
service.PluginStateStarting, first.BinarySHA256,
))
second := *first
second.Version = "1.1.0"
second.Manifest.Version = second.Version
second.BinarySHA256 = strings.Repeat("b", 64)
second.ArtifactData = []byte("second-package")
_, err = repo.Install(ctx, &second, bindings)
require.ErrorIs(t, err, service.ErrPluginStateChanged)
bindings[0].Enabled = false
require.NoError(t, repo.UpdateBindingsAndState(
ctx, installed.ID, bindings, service.PluginStateDisabled, "", nil, "", first.BinarySHA256,
))
replaced, err := repo.Install(ctx, &second, bindings)
require.NoError(t, err)
require.Equal(t, installed.ID, replaced.ID)
err = repo.Delete(ctx, replaced.ID, first.BinarySHA256)
require.True(t, errors.Is(err, service.ErrPluginStateChanged))
require.NoError(t, repo.Delete(ctx, replaced.ID, second.BinarySHA256))
}