pool_test.mx raw

   1  package pool
   2  
   3  import "testing"
   4  
   5  // TestNewPoolSizes pins NewPool's contract: Len is exactly n, every slot starts
   6  // idle, and Busy is writable by the caller (the pool only owns the bookkeeping).
   7  func TestNewPoolSizes(t *testing.T) {
   8  	zero := NewPool(0)
   9  	if zero.Len() != 0 {
  10  		t.Fatalf("NewPool(0).Len() = %d", zero.Len())
  11  	}
  12  	if zero.IdleIndex() != -1 {
  13  		t.Fatalf("NewPool(0).IdleIndex() = %d", zero.IdleIndex())
  14  	}
  15  
  16  	one := NewPool(1)
  17  	if one.Len() != 1 {
  18  		t.Fatalf("NewPool(1).Len() = %d", one.Len())
  19  	}
  20  	if one.Busy[0] {
  21  		t.Fatal("NewPool(1) slot 0 must start idle")
  22  	}
  23  	if one.IdleIndex() != 0 {
  24  		t.Fatalf("NewPool(1).IdleIndex() = %d", one.IdleIndex())
  25  	}
  26  
  27  	three := NewPool(3)
  28  	if three.Len() != 3 {
  29  		t.Fatalf("NewPool(3).Len() = %d", three.Len())
  30  	}
  31  	for i := 0; i < 3; i++ {
  32  		if three.Busy[i] {
  33  			t.Fatalf("NewPool(3) slot %d must start idle", i)
  34  		}
  35  	}
  36  }
  37  
  38  // TestIdleIndexScanOrder pins that IdleIndex returns the lowest idle index and
  39  // advances as slots are marked busy, then recovers when one is released.
  40  func TestIdleIndexScanOrder(t *testing.T) {
  41  	p := NewPool(3)
  42  	if p.IdleIndex() != 0 {
  43  		t.Fatalf("all idle -> %d, want 0", p.IdleIndex())
  44  	}
  45  
  46  	p.Busy[0] = true
  47  	if p.IdleIndex() != 1 {
  48  		t.Fatalf("slot 0 busy -> %d, want 1", p.IdleIndex())
  49  	}
  50  
  51  	p.Busy[1] = true
  52  	if p.IdleIndex() != 2 {
  53  		t.Fatalf("slots 0,1 busy -> %d, want 2", p.IdleIndex())
  54  	}
  55  
  56  	p.Busy[2] = true
  57  	if p.IdleIndex() != -1 {
  58  		t.Fatalf("all busy -> %d, want -1", p.IdleIndex())
  59  	}
  60  
  61  	// Freeing a lower slot wins the scan again.
  62  	p.Busy[1] = false
  63  	if p.IdleIndex() != 1 {
  64  		t.Fatalf("slot 1 freed -> %d, want 1", p.IdleIndex())
  65  	}
  66  }
  67  
  68  // TestSingleWorkerBusyFlips covers the 1-worker pool: either the only slot is
  69  // idle (index 0) or the pool reports full (-1).
  70  func TestSingleWorkerBusyFlips(t *testing.T) {
  71  	p := NewPool(1)
  72  	if p.IdleIndex() != 0 {
  73  		t.Fatalf("1 worker idle -> %d, want 0", p.IdleIndex())
  74  	}
  75  	p.Busy[0] = true
  76  	if p.IdleIndex() != -1 {
  77  		t.Fatalf("1 worker busy -> %d, want -1", p.IdleIndex())
  78  	}
  79  	p.Busy[0] = false
  80  	if p.IdleIndex() != 0 {
  81  		t.Fatalf("1 worker released -> %d, want 0", p.IdleIndex())
  82  	}
  83  }
  84