| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- package repository
- import (
- "sync"
- "testing"
- "time"
- "job-cheng-xing/model"
- )
- func strPtr(s string) *string { return &s }
- func TestMemoryRepo_CreateAndFind(t *testing.T) {
- repo := NewMemoryRepo()
- order := &model.Order{
- ID: "ord_001",
- Status: model.StatusPending,
- ServiceTime: time.Now(),
- Duration: 120,
- Address: "北京朝阳",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- }
- err := repo.Create(order)
- if err != nil {
- t.Fatalf("Create failed: %v", err)
- }
- found, err := repo.FindByID("ord_001")
- if err != nil {
- t.Fatalf("FindByID failed: %v", err)
- }
- if found.ID != "ord_001" {
- t.Errorf("expected ord_001, got %s", found.ID)
- }
- }
- func TestMemoryRepo_FindByID_NotFound(t *testing.T) {
- repo := NewMemoryRepo()
- _, err := repo.FindByID("nonexistent")
- if err != model.ErrNotFound {
- t.Errorf("expected ErrNotFound, got %v", err)
- }
- }
- func TestMemoryRepo_Update_CAS_Success(t *testing.T) {
- repo := NewMemoryRepo()
- order := &model.Order{
- ID: "ord_001",
- Status: model.StatusPending,
- ServiceTime: time.Now(),
- Duration: 120,
- Address: "北京朝阳",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- }
- repo.Create(order)
- newOrder := &model.Order{
- Status: model.StatusAccepted,
- ProviderID: strPtr("prov_001"),
- UpdatedAt: time.Now(),
- }
- err := repo.Update("ord_001", model.StatusPending, newOrder)
- if err != nil {
- t.Fatalf("Update failed: %v", err)
- }
- found, _ := repo.FindByID("ord_001")
- if found.Status != model.StatusAccepted {
- t.Errorf("expected accepted, got %s", found.Status)
- }
- if *found.ProviderID != "prov_001" {
- t.Errorf("expected prov_001, got %s", *found.ProviderID)
- }
- }
- func TestMemoryRepo_Update_CAS_Fail_WrongStatus(t *testing.T) {
- repo := NewMemoryRepo()
- order := &model.Order{
- ID: "ord_001",
- Status: model.StatusPending,
- }
- repo.Create(order)
- newOrder := &model.Order{Status: model.StatusCanceled}
- err := repo.Update("ord_001", model.StatusAccepted, newOrder)
- if err != model.ErrStatusConflict {
- t.Errorf("expected ErrStatusConflict, got %v", err)
- }
- }
- func TestMemoryRepo_ConcurrentAccept(t *testing.T) {
- repo := NewMemoryRepo()
- order := &model.Order{
- ID: "ord_001",
- Status: model.StatusPending,
- ServiceTime: time.Now(),
- Duration: 120,
- Address: "北京朝阳",
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- }
- repo.Create(order)
- const numGoroutines = 50
- var wg sync.WaitGroup
- results := make(chan error, numGoroutines)
- for i := 0; i < numGoroutines; i++ {
- wg.Add(1)
- go func(idx int) {
- defer wg.Done()
- pid := "prov_" + string(rune('a'+idx%26)) + string(rune('0'+idx/26))
- newOrder := &model.Order{
- Status: model.StatusAccepted,
- ProviderID: &pid,
- UpdatedAt: time.Now(),
- }
- results <- repo.Update("ord_001", model.StatusPending, newOrder)
- }(i)
- }
- wg.Wait()
- close(results)
- successCount := 0
- failCount := 0
- for err := range results {
- if err == nil {
- successCount++
- } else if err == model.ErrStatusConflict {
- failCount++
- } else {
- t.Errorf("unexpected error: %v", err)
- }
- }
- if successCount != 1 {
- t.Errorf("expected exactly 1 success, got %d", successCount)
- }
- if failCount != numGoroutines-1 {
- t.Errorf("expected %d failures, got %d", numGoroutines-1, failCount)
- }
- found, _ := repo.FindByID("ord_001")
- if found.ProviderID == nil {
- t.Fatal("expected ProviderID to be set")
- }
- t.Logf("winner provider: %s", *found.ProviderID)
- }
|