package db
import (
"context"
"database/sql"
"path/filepath"
"testing"
"tangled.org/core/spindle/models"
)
func TestMakeAcceptsPrebackfilledArtifactIdentity(t *testing.T) {
path := filepath.Join(t.TempDir(), "spindle.db")
legacy, err := sql.Open("sqlite3", path)
if err != nil {
t.Fatalf("open legacy database: %v", err)
}
if _, err := legacy.Exec(`
create table mill_artifacts (
id integer primary key autoincrement,
lease_id text not null,
repo_did text not null,
knot text not null default '',
rkey text not null default '',
workflow text not null,
ref text not null,
hash text not null
);
insert into mill_artifacts (
id, lease_id, repo_did, knot, rkey, workflow, ref, hash
) values (
1, 'legacy-lease', 'did:plc:legacy-repo', 'knot', 'rkey',
'build.yml', 'legacy-ref', 'legacy-hash'
);
`); err != nil {
legacy.Close()
t.Fatalf("seed legacy database: %v", err)
}
if err := legacy.Close(); err != nil {
t.Fatalf("close legacy database: %v", err)
}
d, err := Make(context.Background(), path)
if err != nil {
t.Fatalf("Make: %v", err)
}
t.Cleanup(func() { d.Close() })
wid := models.WorkflowId{PipelineId: models.PipelineId("rkey"), Name: "build.yml"}
log, err := d.GetFinishedLog(wid)
if err != nil {
t.Fatalf("GetFinishedLog(legacy): %v", err)
}
if log.LeaseID != "legacy-lease" || log.Ref != "legacy-ref" {
t.Fatalf("GetFinishedLog(legacy) = %+v", log)
}
newWID := models.WorkflowId{PipelineId: models.PipelineId("new-rkey"), Name: "build.yml"}
if err := d.SaveArtifactRef("new-lease", "did:plc:repo", newWID, "new-ref", "new-hash"); err != nil {
t.Fatalf("SaveArtifactRef: %v", err)
}
}
func TestMakeMigratesLegacyMillArtifactsRepoDID(t *testing.T) {
path := filepath.Join(t.TempDir(), "spindle.db")
legacy, err := sql.Open("sqlite3", path)
if err != nil {
t.Fatalf("open legacy database: %v", err)
}
if _, err := legacy.Exec(`
create table mill_artifacts (
id integer primary key autoincrement,
lease_id text not null,
knot text not null,
rkey text not null,
workflow text not null,
ref text not null,
hash text not null
);
create table mill_leases (
lease_id text primary key,
node_id text not null,
epoch text not null,
engine text not null,
knot text not null,
rkey text not null,
workflow text not null,
state text not null,
repo_did text
);
insert into mill_leases (
lease_id, node_id, epoch, engine, knot, rkey, workflow, state, repo_did
) values (
'legacy-lease', 'node', 'epoch', 'engine', 'knot', 'rkey',
'legacy-workflow', 'done', 'did:plc:legacy-repo'
);
insert into mill_artifacts (lease_id, knot, rkey, workflow, ref, hash)
values ('legacy-lease', 'knot', 'rkey', 'legacy-workflow', 'legacy-ref', 'legacy-hash');
`); err != nil {
legacy.Close()
t.Fatalf("seed legacy database: %v", err)
}
if err := legacy.Close(); err != nil {
t.Fatalf("close legacy database: %v", err)
}
d, err := Make(context.Background(), path)
if err != nil {
t.Fatalf("Make: %v", err)
}
t.Cleanup(func() { d.Close() })
var repoDID string
if err := d.QueryRow(`select repo_did from mill_artifacts where lease_id = 'legacy-lease'`).Scan(&repoDID); err != nil {
t.Fatalf("query migrated artifact: %v", err)
}
if repoDID != "did:plc:legacy-repo" {
t.Fatalf("legacy repo_did = %q, want did:plc:legacy-repo", repoDID)
}
}
func TestGetFinishedLogMatchesPipelineAndWorkflow(t *testing.T) {
d := newTestDB(t)
wid := models.WorkflowId{PipelineId: models.PipelineId("pipeline-1"), Name: "build.yml"}
otherPipeline := models.WorkflowId{PipelineId: models.PipelineId("pipeline-2"), Name: wid.Name}
for _, artifact := range []struct {
leaseID string
wid models.WorkflowId
ref string
}{
{"wanted-old", wid, "wanted-old.log"},
{"other-pipeline", otherPipeline, "other-pipeline.log"},
{"wanted-new", wid, "wanted-new.log"},
} {
if err := d.SaveArtifactRef(artifact.leaseID, "did:plc:repo", artifact.wid, artifact.ref, "hash"); err != nil {
t.Fatalf("SaveArtifactRef(%s): %v", artifact.leaseID, err)
}
}
log, err := d.GetFinishedLog(wid)
if err != nil {
t.Fatalf("GetFinishedLog: %v", err)
}
if log.LeaseID != "wanted-new" || log.Ref != "wanted-new.log" {
t.Fatalf("GetFinishedLog = %+v, want newest artifact for exact workflow identity", log)
}
}
func TestFinishedLogRejectsIncompleteWorkflowIdentity(t *testing.T) {
d := newTestDB(t)
for _, wid := range []models.WorkflowId{
{PipelineId: models.PipelineId(""), Name: "build.yml"},
{PipelineId: models.PipelineId("rkey")},
} {
if _, err := d.GetFinishedLog(wid); err == nil {
t.Fatalf("GetFinishedLog(%+v) succeeded", wid)
}
if err := d.SaveArtifactRef("lease", "did:plc:repo", wid, "ref", "hash"); err == nil {
t.Fatalf("SaveArtifactRef(%+v) succeeded", wid)
}
}
}