WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/Tencent/WeKnora/internal/models/embedding"
|
||||
"github.com/Tencent/WeKnora/internal/types"
|
||||
"github.com/Tencent/WeKnora/internal/types/interfaces"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// embeddingInitFailureRepo captures the update made by processChunks. The
|
||||
// real repository has the same UpdateKnowledge contract; this small fake keeps
|
||||
// the test focused on the terminal state transition.
|
||||
type embeddingInitFailureRepo struct {
|
||||
interfaces.KnowledgeRepository
|
||||
knowledge *types.Knowledge
|
||||
updated int
|
||||
}
|
||||
|
||||
func (r *embeddingInitFailureRepo) GetKnowledgeByID(context.Context, uint64, string) (*types.Knowledge, error) {
|
||||
return r.knowledge, nil
|
||||
}
|
||||
|
||||
func (r *embeddingInitFailureRepo) UpdateKnowledge(_ context.Context, knowledge *types.Knowledge) error {
|
||||
r.updated++
|
||||
r.knowledge = knowledge
|
||||
return nil
|
||||
}
|
||||
|
||||
type embeddingInitFailureModelService struct {
|
||||
interfaces.ModelService
|
||||
err error
|
||||
}
|
||||
|
||||
func (s embeddingInitFailureModelService) GetEmbeddingModel(context.Context, string) (embedding.Embedder, error) {
|
||||
return nil, s.err
|
||||
}
|
||||
|
||||
// TestProcessChunks_EmbeddingModelFailurePersistsFailedState guards the
|
||||
// failure path that previously just returned from processChunks. A provider
|
||||
// configuration error must be visible to callers and the persisted stage
|
||||
// trace; otherwise the knowledge row remains "processing" indefinitely.
|
||||
func TestProcessChunks_EmbeddingModelFailurePersistsFailedState(t *testing.T) {
|
||||
knowledge := &types.Knowledge{
|
||||
ID: "knowledge-embedding-failure",
|
||||
TenantID: 1,
|
||||
KnowledgeBaseID: "kb-1",
|
||||
ParseStatus: types.ParseStatusProcessing,
|
||||
}
|
||||
repo := &embeddingInitFailureRepo{knowledge: knowledge}
|
||||
failure := errors.New("embedding provider credentials are invalid")
|
||||
|
||||
// Use the real span tracker against the test SQLite schema so this also
|
||||
// proves the embedding stage is failed rather than left running.
|
||||
tracker, db := setupSpanTrackerTest(t)
|
||||
_, attempt, err := tracker.OpenAttempt(context.Background(), knowledge.ID, "trace")
|
||||
require.NoError(t, err)
|
||||
|
||||
tenant := &types.Tenant{ID: 1}
|
||||
ctx := context.WithValue(context.Background(), types.TenantInfoContextKey, tenant)
|
||||
ctx = withAttempt(ctx, attempt)
|
||||
svc := &knowledgeService{
|
||||
repo: repo,
|
||||
modelService: embeddingInitFailureModelService{err: failure},
|
||||
spanTracker: tracker,
|
||||
}
|
||||
kb := &types.KnowledgeBase{
|
||||
ID: "kb-1",
|
||||
EmbeddingModelID: "missing-model",
|
||||
IndexingStrategy: types.IndexingStrategy{VectorEnabled: true},
|
||||
}
|
||||
|
||||
svc.processChunks(ctx, kb, knowledge, nil)
|
||||
|
||||
require.Equal(t, 1, repo.updated, "failure must be persisted immediately")
|
||||
require.Equal(t, types.ParseStatusFailed, knowledge.ParseStatus)
|
||||
require.Equal(t, failure.Error(), knowledge.ErrorMessage)
|
||||
require.False(t, knowledge.UpdatedAt.IsZero())
|
||||
|
||||
var row struct{ Status, ErrorCode, ErrorMessage string }
|
||||
require.NoError(t, db.Table("knowledge_processing_spans").
|
||||
Select("status, error_code, error_message").
|
||||
Where("knowledge_id = ? AND attempt = ? AND name = ?", knowledge.ID, attempt, types.StageEmbedding).
|
||||
First(&row).Error)
|
||||
require.Equal(t, types.SpanStatusFailed, row.Status)
|
||||
require.Equal(t, "EMBEDDING_PROVIDER_FAIL", row.ErrorCode)
|
||||
require.Contains(t, row.ErrorMessage, "get embedding model failed")
|
||||
}
|
||||
Reference in New Issue
Block a user