package store import ( "context" "testing" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" "gcy_hpc_server/internal/model" ) func newTestDB(t *testing.T) *gorm.DB { t.Helper() db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), }) if err != nil { t.Fatalf("open sqlite: %v", err) } if err := db.AutoMigrate(&model.JobTemplate{}); err != nil { t.Fatalf("auto migrate: %v", err) } return db } func TestTemplateStore_List(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) s.Create(context.Background(), &model.CreateTemplateRequest{Name: "job-1", Script: "echo 1"}) s.Create(context.Background(), &model.CreateTemplateRequest{Name: "job-2", Script: "echo 2"}) templates, total, err := s.List(context.Background(), 1, 10) if err != nil { t.Fatalf("List() error = %v", err) } if total != 2 { t.Errorf("total = %d, want 2", total) } if len(templates) != 2 { t.Fatalf("len(templates) = %d, want 2", len(templates)) } // DESC order, so job-2 is first if templates[0].Name != "job-2" { t.Errorf("templates[0].Name = %q, want %q", templates[0].Name, "job-2") } } func TestTemplateStore_List_Page2(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) for i := 0; i < 15; i++ { s.Create(context.Background(), &model.CreateTemplateRequest{ Name: "job-" + string(rune('A'+i)), Script: "echo", }) } templates, total, err := s.List(context.Background(), 2, 10) if err != nil { t.Fatalf("List() error = %v", err) } if total != 15 { t.Errorf("total = %d, want 15", total) } if len(templates) != 5 { t.Fatalf("len(templates) = %d, want 5", len(templates)) } } func TestTemplateStore_GetByID(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) id, _ := s.Create(context.Background(), &model.CreateTemplateRequest{ Name: "test-job", Script: "echo hi", Partition: "batch", QOS: "normal", CPUs: 2, Memory: "4G", }) tpl, err := s.GetByID(context.Background(), id) if err != nil { t.Fatalf("GetByID() error = %v", err) } if tpl == nil { t.Fatal("GetByID() returned nil") } if tpl.Name != "test-job" { t.Errorf("Name = %q, want %q", tpl.Name, "test-job") } if tpl.CPUs != 2 { t.Errorf("CPUs = %d, want 2", tpl.CPUs) } } func TestTemplateStore_GetByID_NotFound(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) tpl, err := s.GetByID(context.Background(), 999) if err != nil { t.Fatalf("GetByID() error = %v, want nil", err) } if tpl != nil { t.Fatal("GetByID() should return nil for not found") } } func TestTemplateStore_Create(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) id, err := s.Create(context.Background(), &model.CreateTemplateRequest{ Name: "new-job", Script: "echo", Partition: "gpu", }) if err != nil { t.Fatalf("Create() error = %v", err) } if id == 0 { t.Fatal("Create() returned id=0") } } func TestTemplateStore_Update(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) id, _ := s.Create(context.Background(), &model.CreateTemplateRequest{ Name: "old", Script: "echo", }) err := s.Update(context.Background(), id, &model.UpdateTemplateRequest{ Name: "updated", Script: "echo new", CPUs: 8, }) if err != nil { t.Fatalf("Update() error = %v", err) } tpl, _ := s.GetByID(context.Background(), id) if tpl.Name != "updated" { t.Errorf("Name = %q, want %q", tpl.Name, "updated") } if tpl.CPUs != 8 { t.Errorf("CPUs = %d, want 8", tpl.CPUs) } } func TestTemplateStore_Update_Partial(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) id, _ := s.Create(context.Background(), &model.CreateTemplateRequest{ Name: "original", Script: "echo orig", Partition: "batch", }) err := s.Update(context.Background(), id, &model.UpdateTemplateRequest{ Name: "renamed", }) if err != nil { t.Fatalf("Update() error = %v", err) } tpl, _ := s.GetByID(context.Background(), id) if tpl.Name != "renamed" { t.Errorf("Name = %q, want %q", tpl.Name, "renamed") } // Script and Partition should be unchanged if tpl.Script != "echo orig" { t.Errorf("Script = %q, want %q", tpl.Script, "echo orig") } if tpl.Partition != "batch" { t.Errorf("Partition = %q, want %q", tpl.Partition, "batch") } } func TestTemplateStore_Delete(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) id, _ := s.Create(context.Background(), &model.CreateTemplateRequest{ Name: "to-delete", Script: "echo", }) err := s.Delete(context.Background(), id) if err != nil { t.Fatalf("Delete() error = %v", err) } tpl, _ := s.GetByID(context.Background(), id) if tpl != nil { t.Fatal("Delete() did not remove the record") } } func TestTemplateStore_Delete_NotFound(t *testing.T) { db := newTestDB(t) s := NewTemplateStore(db) err := s.Delete(context.Background(), 999) if err != nil { t.Fatalf("Delete() should not error for non-existent record, got: %v", err) } }