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  }