78 lines
2.8 KiB
Go
78 lines
2.8 KiB
Go
package store
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"git.ipao.vip/rogee/go-sip/internal/configread"
|
|
"git.ipao.vip/rogee/go-sip/internal/contract"
|
|
)
|
|
|
|
func TestRejectedDataPersistsOriginalAndFeedbackWithoutExecuting(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "current.db")
|
|
s, err := Open(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer s.Close()
|
|
if err := s.SaveSnapshot(currentStoreSnapshot(t)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := s.ApplyDiscoverySnapshot(currentDispatcherID, []configread.DiscoveredTask{{TaskID: "task-asr", TenantID: 1001, TaskRevision: 1, Status: "running"}}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
raw := []byte(`{"event_id":"bad-original","event_type":"task.control","dispatcher_id":"` + currentDispatcherID + `","tenant_id":1001,"payload":{"task_id":"task-asr","action":"resume","reason":"PRIVATE ORIGINAL"}}`)
|
|
cause := contract.ValidateCurrent("mq", raw)
|
|
if cause == nil {
|
|
t.Fatal("fixture unexpectedly valid")
|
|
}
|
|
for i := 0; i < 2; i++ {
|
|
if err := s.RejectData(currentDispatcherID, raw, cause); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
var body []byte
|
|
var count int
|
|
if err := s.db.QueryRow(`SELECT count(*),body FROM dispatcher_outbox WHERE event_id='bad-original'`).Scan(&count, &body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if count != 1 || contract.ValidateCurrent("mq", body) != nil || !bytes.Contains(body, []byte(`"rejected"`)) || !bytes.Contains(body, []byte("issued_at")) || bytes.Contains(body, []byte("PRIVATE ORIGINAL")) {
|
|
t.Fatalf("incorrect rejection: %s", body)
|
|
}
|
|
if err := s.db.QueryRow(`SELECT count(*) FROM dispatcher_inbox`).Scan(&count); err != nil || count != 0 {
|
|
t.Fatalf("rejection admitted a call: %d %v", count, err)
|
|
}
|
|
files, err := filepath.Glob(filepath.Join(filepath.Dir(path), "rejected-data", "*.json"))
|
|
if err != nil || len(files) != 1 {
|
|
t.Fatalf("original evidence absent: %v %v", files, err)
|
|
}
|
|
info, err := os.Stat(files[0])
|
|
if err != nil || info.Mode().Perm() != 0600 {
|
|
t.Fatalf("original not private: %v %v", info, err)
|
|
}
|
|
saved, err := os.ReadFile(files[0])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var evidence struct{ Original []byte }
|
|
if json.Unmarshal(saved, &evidence) != nil || !bytes.Equal(evidence.Original, raw) {
|
|
t.Fatal("saved bytes differ from original")
|
|
}
|
|
}
|
|
func TestUnidentifiableOrForeignRejectedDataDoesNotFabricateFeedback(t *testing.T) {
|
|
s, err := Open(filepath.Join(t.TempDir(), "current.db"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer s.Close()
|
|
for _, raw := range []string{`{`, `{"event_type":"task.control"}`, `{"event_id":"x","event_type":"task.control","dispatcher_id":"00000000-0000-0000-0000-000000000001","tenant_id":1001}`} {
|
|
if err := s.RejectData(currentDispatcherID, []byte(raw), errors.New("invalid structure")); !errors.Is(err, ErrUnidentifiableData) {
|
|
t.Fatalf("unidentifiable/foreign data accepted: %v", err)
|
|
}
|
|
}
|
|
}
|