github.com/technosophos/deis@v1.7.1-0.20150915173815-f9005256004b/deisctl/backend/fleet/fleet_test.go (about) 1 package fleet 2 3 import ( 4 "bytes" 5 "fmt" 6 "sync" 7 "testing" 8 9 "github.com/deis/deis/deisctl/config/model" 10 "github.com/deis/deis/deisctl/test/mock" 11 12 "github.com/coreos/fleet/machine" 13 "github.com/coreos/fleet/schema" 14 ) 15 16 type stubFleetClient struct { 17 testUnits []*schema.Unit 18 testUnitStates []*schema.UnitState 19 testMachineStates []machine.MachineState 20 unitStatesMutex *sync.Mutex 21 unitsMutex *sync.Mutex 22 } 23 24 func (c *stubFleetClient) Machines() ([]machine.MachineState, error) { 25 return c.testMachineStates, nil 26 } 27 func (c *stubFleetClient) Unit(name string) (*schema.Unit, error) { 28 c.unitsMutex.Lock() 29 defer c.unitsMutex.Unlock() 30 31 for _, unit := range c.testUnits { 32 if unit.Name == name { 33 return unit, nil 34 } 35 } 36 37 return nil, fmt.Errorf("Unit %s not found", name) 38 } 39 func (c *stubFleetClient) Units() ([]*schema.Unit, error) { 40 c.unitsMutex.Lock() 41 defer c.unitsMutex.Unlock() 42 43 return c.testUnits, nil 44 } 45 func (c *stubFleetClient) UnitStates() ([]*schema.UnitState, error) { 46 c.unitStatesMutex.Lock() 47 defer c.unitStatesMutex.Unlock() 48 49 return c.testUnitStates, nil 50 } 51 52 type failingFleetClient struct { 53 stubFleetClient 54 } 55 56 func (c *failingFleetClient) SetUnitTargetState(name, target string) error { 57 if err := c.stubFleetClient.SetUnitTargetState(name, target); err != nil { 58 return err 59 } 60 61 last := len(c.testUnitStates) - 1 62 c.testUnitStates[last] = &schema.UnitState{ 63 Name: name, 64 SystemdSubState: "failed", 65 SystemdActiveState: "failed", 66 } 67 68 return nil 69 } 70 71 func (c *stubFleetClient) SetUnitTargetState(name, target string) error { 72 73 var activeState string 74 var subState string 75 76 switch target { 77 case "loaded": 78 activeState = "inactive" 79 subState = "dead" 80 case "launched": 81 activeState = "active" 82 subState = "running" 83 } 84 85 unit, err := c.Unit(name) 86 87 if err != nil { 88 return err 89 } 90 91 c.unitsMutex.Lock() 92 unit.DesiredState = target 93 c.unitsMutex.Unlock() 94 95 c.unitStatesMutex.Lock() 96 defer c.unitStatesMutex.Unlock() 97 98 for _, unitState := range c.testUnitStates { 99 if name == unitState.Name { 100 unitState.SystemdSubState = subState 101 unitState.SystemdActiveState = activeState 102 return nil 103 } 104 } 105 106 c.testUnitStates = append(c.testUnitStates, &schema.UnitState{Name: name, SystemdSubState: subState, SystemdActiveState: activeState}) 107 108 return nil 109 } 110 111 func (c *stubFleetClient) CreateUnit(unit *schema.Unit) error { 112 c.unitsMutex.Lock() 113 c.testUnits = append(c.testUnits, unit) 114 c.unitsMutex.Unlock() 115 116 return nil 117 } 118 119 func (c *stubFleetClient) DestroyUnit(name string) error { 120 c.unitsMutex.Lock() 121 for i := len(c.testUnits) - 1; i >= 0; i-- { 122 if c.testUnits[i].Name == name { 123 c.testUnits = append(c.testUnits[:i], c.testUnits[i+1:]...) 124 } 125 } 126 c.unitsMutex.Unlock() 127 128 return nil 129 } 130 131 func newOutErr() *outErr { 132 return &outErr{ 133 &syncBuffer{}, 134 &syncBuffer{}, 135 } 136 } 137 138 // Wrap output and error streams for ease of testing. 139 type outErr struct { 140 out, ew buffer 141 } 142 143 // buffer represents a buffer for collecting written test output. 144 // 145 // This is used only in testing, so add more bytes.Buffer methods as needed. 146 type buffer interface { 147 Bytes() []byte 148 String() string 149 Write([]byte) (int, error) 150 } 151 152 // syncBuffer simply synchronizes writes on a bytes.Buffer. 153 type syncBuffer struct { 154 bytes.Buffer 155 mx sync.RWMutex 156 } 157 158 func (s *syncBuffer) Write(b []byte) (int, error) { 159 s.mx.Lock() 160 defer s.mx.Unlock() 161 return s.Buffer.Write(b) 162 } 163 164 func (s *syncBuffer) String() string { 165 s.mx.RLock() 166 defer s.mx.RUnlock() 167 return s.Buffer.String() 168 } 169 170 func (s *syncBuffer) Bytes() []byte { 171 s.mx.RLock() 172 defer s.mx.RUnlock() 173 return s.Buffer.Bytes() 174 } 175 176 func TestNewClient(t *testing.T) { 177 t.Parallel() 178 179 // set required flags 180 Flags.Endpoint = "http://127.0.0.1:4001" 181 182 testConfigBackend := mock.ConfigBackend{Expected: []*model.ConfigNode{}} 183 184 // instantiate client 185 _, err := NewClient(testConfigBackend) 186 if err != nil { 187 t.Fatal(err) 188 } 189 }