github.com/technosophos/deis@v1.7.1-0.20150915173815-f9005256004b/deisctl/cmd/cmd_test.go (about)

     1  package cmd
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"net/http/httptest"
    10  	"reflect"
    11  	"strings"
    12  	"sync"
    13  	"testing"
    14  
    15  	"github.com/deis/deis/deisctl/backend"
    16  	"github.com/deis/deis/deisctl/config"
    17  	"github.com/deis/deis/deisctl/config/model"
    18  	"github.com/deis/deis/deisctl/test/mock"
    19  	"github.com/deis/deis/deisctl/units"
    20  )
    21  
    22  type backendStub struct {
    23  	startedUnits     []string
    24  	stoppedUnits     []string
    25  	installedUnits   []string
    26  	uninstalledUnits []string
    27  	restartedUnits   []string
    28  	expected         bool
    29  }
    30  
    31  func (backend *backendStub) Create(targets []string, wg *sync.WaitGroup, out, ew io.Writer) {
    32  	backend.installedUnits = append(backend.installedUnits, targets...)
    33  }
    34  func (backend *backendStub) Destroy(targets []string, wg *sync.WaitGroup, out, ew io.Writer) {
    35  	backend.uninstalledUnits = append(backend.uninstalledUnits, targets...)
    36  }
    37  func (backend *backendStub) Start(targets []string, wg *sync.WaitGroup, out, ew io.Writer) {
    38  	backend.startedUnits = append(backend.startedUnits, targets...)
    39  }
    40  func (backend *backendStub) Stop(targets []string, wg *sync.WaitGroup, out, ew io.Writer) {
    41  	backend.stoppedUnits = append(backend.stoppedUnits, targets...)
    42  }
    43  func (backend *backendStub) Scale(component string, num int, wg *sync.WaitGroup, out, ew io.Writer) {
    44  	switch {
    45  	case component == "router" && num == 3:
    46  		backend.expected = true
    47  	case component == "registry" && num == 4:
    48  		backend.expected = true
    49  	default:
    50  		backend.expected = false
    51  	}
    52  }
    53  func (backend *backendStub) RollingRestart(target string, wg *sync.WaitGroup, out, ew io.Writer) {
    54  	backend.restartedUnits = append(backend.restartedUnits, target)
    55  }
    56  
    57  func (backend *backendStub) ListUnits() error {
    58  	return nil
    59  }
    60  func (backend *backendStub) ListUnitFiles() error {
    61  	return nil
    62  }
    63  func (backend *backendStub) Status(target string) error {
    64  	if target == "controller" || target == "builder" {
    65  		return nil
    66  	}
    67  	return errors.New("Test Error")
    68  }
    69  func (backend *backendStub) Journal(target string) error {
    70  	if target == "controller" || target == "builder" {
    71  		return nil
    72  	}
    73  	return errors.New("Test Error")
    74  }
    75  func (backend *backendStub) SSH(target string) error {
    76  	if target == "controller" {
    77  		return nil
    78  	}
    79  	return errors.New("Error")
    80  }
    81  func (backend *backendStub) SSHExec(target, command string) error {
    82  	if target == "controller" && command == "sh" {
    83  		return nil
    84  	}
    85  	return errors.New("Error")
    86  }
    87  
    88  func (backend *backendStub) Dock(target string, command []string) error {
    89  	return nil
    90  }
    91  
    92  var _ backend.Backend = &backendStub{}
    93  
    94  func fakeCheckKeys(cb config.Backend) error {
    95  	return nil
    96  }
    97  
    98  type fakeHTTPServer struct{}
    99  
   100  func (fakeHTTPServer) ServeHTTP(res http.ResponseWriter, req *http.Request) {
   101  
   102  	if strings.Split(req.URL.Path, "/")[1] != "v1.7.2" {
   103  		res.WriteHeader(http.StatusNotFound)
   104  	}
   105  
   106  	res.Write([]byte("test"))
   107  }
   108  
   109  func TestRefreshUnits(t *testing.T) {
   110  	t.Parallel()
   111  
   112  	name, err := ioutil.TempDir("", "deisctl")
   113  
   114  	if err != nil {
   115  		t.Error(err)
   116  	}
   117  
   118  	handler := fakeHTTPServer{}
   119  	server := httptest.NewServer(handler)
   120  	defer server.Close()
   121  
   122  	err = RefreshUnits(name, "v1.7.2", server.URL+"/")
   123  
   124  	if err != nil {
   125  		t.Error(err)
   126  	}
   127  
   128  	files, err := ioutil.ReadDir(name)
   129  
   130  	// There will be a "decorators" subdirectory and that shouldn't be
   131  	// counted as a unit when making the upcoming assertion.
   132  	numFiles := len(files) - 1
   133  
   134  	if len(units.Names) != numFiles {
   135  		t.Error(fmt.Errorf("Expected %d units, Got %d", len(units.Names), numFiles))
   136  	}
   137  
   138  	for _, unit := range units.Names {
   139  		found := false
   140  
   141  		for _, file := range files {
   142  			if unit+".service" == file.Name() {
   143  				found = true
   144  			}
   145  		}
   146  
   147  		if found == false {
   148  			t.Error(fmt.Errorf("Expected to find %s in %v", unit, files))
   149  		}
   150  	}
   151  }
   152  
   153  func TestRefreshUnitsError(t *testing.T) {
   154  	t.Parallel()
   155  
   156  	name, err := ioutil.TempDir("", "deisctl")
   157  
   158  	if err != nil {
   159  		t.Error(err)
   160  	}
   161  
   162  	handler := fakeHTTPServer{}
   163  	server := httptest.NewServer(handler)
   164  	defer server.Close()
   165  
   166  	err = RefreshUnits(name, "foo", server.URL+"/")
   167  	result := err.Error()
   168  	expected := "404 Not Found"
   169  
   170  	if result != expected {
   171  		t.Error(fmt.Errorf("Expected %s, Got %s", expected, result))
   172  	}
   173  }
   174  
   175  func TestListUnits(t *testing.T) {
   176  	t.Parallel()
   177  
   178  	b := backendStub{installedUnits: []string{"router@1", "router@2"}}
   179  
   180  	if ListUnits(&b) != nil {
   181  		t.Error("unexpected error")
   182  	}
   183  }
   184  
   185  func TestListUnitFiles(t *testing.T) {
   186  	t.Parallel()
   187  
   188  	b := backendStub{}
   189  
   190  	if ListUnitFiles(&b) != nil {
   191  		t.Error("unexpected error")
   192  	}
   193  }
   194  
   195  func TestScaling(t *testing.T) {
   196  	t.Parallel()
   197  
   198  	b := backendStub{expected: false}
   199  	scale := []string{"registry=4", "router=3"}
   200  
   201  	Scale(scale, &b)
   202  
   203  	if b.expected == false {
   204  		t.Error("b.Scale called with unexpected arguements")
   205  	}
   206  }
   207  
   208  func TestScalingNonScalableComponent(t *testing.T) {
   209  	t.Parallel()
   210  
   211  	b := backendStub{}
   212  	expected := "cannot scale controller component"
   213  	err := Scale([]string{"controller=2"}, &b).Error()
   214  
   215  	if err != expected {
   216  		t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err))
   217  	}
   218  }
   219  
   220  func TestScalingInvalidFormat(t *testing.T) {
   221  	t.Parallel()
   222  
   223  	b := backendStub{}
   224  	expected := "Could not parse: controller2"
   225  	err := Scale([]string{"controller2"}, &b).Error()
   226  
   227  	if err != expected {
   228  		t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err))
   229  	}
   230  }
   231  
   232  func TestStart(t *testing.T) {
   233  	t.Parallel()
   234  
   235  	b := backendStub{}
   236  	expected := []string{"router@1", "router@2"}
   237  
   238  	Start(expected, &b)
   239  
   240  	if !reflect.DeepEqual(b.startedUnits, expected) {
   241  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits))
   242  	}
   243  }
   244  
   245  func TestStartPlatform(t *testing.T) {
   246  	t.Parallel()
   247  
   248  	b := backendStub{}
   249  	expected := []string{"store-monitor", "store-daemon", "store-metadata", "store-gateway@*",
   250  		"store-volume", "logger", "logspout", "database", "registry@*", "controller",
   251  		"builder", "publisher", "router@*", "database", "registry@*", "controller",
   252  		"builder", "publisher", "router@*"}
   253  
   254  	Start([]string{"platform"}, &b)
   255  
   256  	if !reflect.DeepEqual(b.startedUnits, expected) {
   257  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits))
   258  	}
   259  }
   260  
   261  func TestStartStatelessPlatform(t *testing.T) {
   262  	t.Parallel()
   263  
   264  	b := backendStub{}
   265  	expected := []string{"logspout", "registry@*", "controller",
   266  		"builder", "publisher", "router@*", "registry@*", "controller",
   267  		"builder", "publisher", "router@*"}
   268  
   269  	Start([]string{"stateless-platform"}, &b)
   270  
   271  	if !reflect.DeepEqual(b.startedUnits, expected) {
   272  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits))
   273  	}
   274  }
   275  
   276  func TestStartSwarm(t *testing.T) {
   277  	t.Parallel()
   278  
   279  	b := backendStub{}
   280  	expected := []string{"swarm-manager", "swarm-node"}
   281  
   282  	Start([]string{"swarm"}, &b)
   283  
   284  	if !reflect.DeepEqual(b.startedUnits, expected) {
   285  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits))
   286  	}
   287  }
   288  
   289  func TestRollingRestart(t *testing.T) {
   290  	t.Parallel()
   291  
   292  	b := backendStub{}
   293  	expected := []string{"router"}
   294  
   295  	RollingRestart("router", &b)
   296  
   297  	if !reflect.DeepEqual(b.restartedUnits, expected) {
   298  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.restartedUnits))
   299  	}
   300  }
   301  
   302  func TestUpgradePrep(t *testing.T) {
   303  	t.Parallel()
   304  
   305  	b := backendStub{}
   306  	expected := []string{"database", "registry@*", "controller", "builder", "logger", "logspout", "store-volume",
   307  		"store-gateway@*", "store-metadata", "store-daemon", "store-monitor"}
   308  
   309  	UpgradePrep(&b)
   310  
   311  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   312  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   313  	}
   314  }
   315  
   316  func TestUpgradeTakeover(t *testing.T) {
   317  	t.Parallel()
   318  	testMock := mock.ConfigBackend{Expected: []*model.ConfigNode{{Key: "/deis/services/app1", Value: "foo", TTL: 10},
   319  		{Key: "/deis/services/app2", Value: "8000", TTL: 10}}}
   320  
   321  	b := backendStub{}
   322  	expectedRestarted := []string{"router"}
   323  	expectedStarted := []string{"publisher", "store-monitor", "store-daemon", "store-metadata",
   324  		"store-gateway@*", "store-volume", "logger", "logspout", "database", "registry@*",
   325  		"controller", "builder", "publisher", "router@*", "database", "registry@*",
   326  		"controller", "builder", "publisher", "router@*"}
   327  
   328  	if err := doUpgradeTakeOver(&b, testMock); err != nil {
   329  		t.Error(fmt.Errorf("Takeover failed: %v", err))
   330  	}
   331  
   332  	if !reflect.DeepEqual(b.restartedUnits, expectedRestarted) {
   333  		t.Error(fmt.Errorf("Expected %v, Got %v", expectedRestarted, b.restartedUnits))
   334  	}
   335  	if !reflect.DeepEqual(b.startedUnits, expectedStarted) {
   336  		t.Error(fmt.Errorf("Expected %v, Got %v", expectedStarted, b.startedUnits))
   337  	}
   338  }
   339  
   340  func TestStop(t *testing.T) {
   341  	t.Parallel()
   342  
   343  	b := backendStub{}
   344  	expected := []string{"router@1", "router@2"}
   345  	Stop(expected, &b)
   346  
   347  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   348  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   349  	}
   350  }
   351  
   352  func TestStopPlatform(t *testing.T) {
   353  	t.Parallel()
   354  
   355  	b := backendStub{}
   356  	expected := []string{"router@*", "publisher", "controller", "builder", "database",
   357  		"registry@*", "logger", "logspout", "store-volume", "store-gateway@*",
   358  		"store-metadata", "store-daemon", "store-monitor"}
   359  	Stop([]string{"platform"}, &b)
   360  
   361  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   362  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   363  	}
   364  }
   365  
   366  func TestStopStatelessPlatform(t *testing.T) {
   367  	t.Parallel()
   368  
   369  	b := backendStub{}
   370  	expected := []string{"router@*", "publisher", "controller", "builder",
   371  		"registry@*", "logspout"}
   372  	Stop([]string{"stateless-platform"}, &b)
   373  
   374  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   375  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   376  	}
   377  }
   378  
   379  func TestStopSwarm(t *testing.T) {
   380  	t.Parallel()
   381  
   382  	b := backendStub{}
   383  	expected := []string{"swarm-node", "swarm-manager"}
   384  	Stop([]string{"swarm"}, &b)
   385  
   386  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   387  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   388  	}
   389  }
   390  
   391  func TestRestart(t *testing.T) {
   392  	t.Parallel()
   393  
   394  	b := backendStub{}
   395  	expected := []string{"router@4", "router@5"}
   396  
   397  	Restart(expected, &b)
   398  
   399  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   400  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   401  	}
   402  	if !reflect.DeepEqual(b.startedUnits, expected) {
   403  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits))
   404  	}
   405  }
   406  
   407  func TestSSH(t *testing.T) {
   408  	t.Parallel()
   409  
   410  	b := backendStub{}
   411  	err := SSH("controller", []string{}, &b)
   412  
   413  	if err != nil {
   414  		t.Error(err)
   415  	}
   416  }
   417  func TestSSHExec(t *testing.T) {
   418  	t.Parallel()
   419  
   420  	b := backendStub{}
   421  	err := SSH("controller", []string{"sh"}, &b)
   422  
   423  	if err != nil {
   424  		t.Error(err)
   425  	}
   426  }
   427  
   428  func TestSSHError(t *testing.T) {
   429  	t.Parallel()
   430  
   431  	b := backendStub{}
   432  	err := SSH("registry", []string{}, &b)
   433  
   434  	if err == nil {
   435  		t.Error("Error expected")
   436  	}
   437  }
   438  
   439  func TestStatus(t *testing.T) {
   440  	t.Parallel()
   441  
   442  	b := backendStub{}
   443  
   444  	if Status([]string{"controller", "builder"}, &b) != nil {
   445  		t.Error("Unexpected Error")
   446  	}
   447  }
   448  
   449  func TestStatusError(t *testing.T) {
   450  	t.Parallel()
   451  
   452  	b := backendStub{}
   453  
   454  	expected := "Test Error"
   455  	err := Status([]string{"blah"}, &b).Error()
   456  
   457  	if err != expected {
   458  		t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err))
   459  	}
   460  }
   461  
   462  func TestJournal(t *testing.T) {
   463  	t.Parallel()
   464  
   465  	b := backendStub{}
   466  
   467  	if Journal([]string{"controller", "builder"}, &b) != nil {
   468  		t.Error("Unexpected Error")
   469  	}
   470  }
   471  
   472  func TestJournalError(t *testing.T) {
   473  	t.Parallel()
   474  
   475  	b := backendStub{}
   476  
   477  	expected := "Test Error"
   478  	err := Journal([]string{"blah"}, &b).Error()
   479  
   480  	if err != expected {
   481  		t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err))
   482  	}
   483  }
   484  
   485  func TestInstall(t *testing.T) {
   486  	t.Parallel()
   487  
   488  	b := backendStub{}
   489  	cb := mock.ConfigBackend{}
   490  
   491  	expected := []string{"router@1", "router@2"}
   492  
   493  	Install(expected, &b, &cb, fakeCheckKeys)
   494  
   495  	if !reflect.DeepEqual(b.installedUnits, expected) {
   496  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits))
   497  	}
   498  }
   499  
   500  func TestInstallPlatform(t *testing.T) {
   501  	t.Parallel()
   502  
   503  	b := backendStub{}
   504  	cb := mock.ConfigBackend{}
   505  
   506  	expected := []string{"store-daemon", "store-monitor", "store-metadata", "store-volume",
   507  		"store-gateway@1", "logger", "logspout", "database", "registry@1",
   508  		"controller", "builder", "publisher", "router@1", "router@2", "router@3"}
   509  
   510  	Install([]string{"platform"}, &b, &cb, fakeCheckKeys)
   511  
   512  	if !reflect.DeepEqual(b.installedUnits, expected) {
   513  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits))
   514  	}
   515  }
   516  
   517  func TestInstallPlatformWithCustomRouterMeshSize(t *testing.T) {
   518  	t.Parallel()
   519  
   520  	b := backendStub{}
   521  	cb := mock.ConfigBackend{}
   522  
   523  	expected := []string{"store-daemon", "store-monitor", "store-metadata", "store-volume",
   524  		"store-gateway@1", "logger", "logspout", "database", "registry@1",
   525  		"controller", "builder", "publisher", "router@1", "router@2", "router@3", "router@4", "router@5"}
   526  	RouterMeshSize = 5
   527  
   528  	Install([]string{"platform"}, &b, &cb, fakeCheckKeys)
   529  	RouterMeshSize = DefaultRouterMeshSize
   530  
   531  	if !reflect.DeepEqual(b.installedUnits, expected) {
   532  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits))
   533  	}
   534  }
   535  
   536  func TestInstallStatelessPlatform(t *testing.T) {
   537  	t.Parallel()
   538  
   539  	b := backendStub{}
   540  	cb := mock.ConfigBackend{}
   541  
   542  	expected := []string{"logspout", "registry@1",
   543  		"controller", "builder", "publisher", "router@1", "router@2", "router@3"}
   544  
   545  	Install([]string{"stateless-platform"}, &b, &cb, fakeCheckKeys)
   546  
   547  	if !reflect.DeepEqual(b.installedUnits, expected) {
   548  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits))
   549  	}
   550  }
   551  
   552  func TestInstallSwarm(t *testing.T) {
   553  	t.Parallel()
   554  
   555  	b := backendStub{}
   556  	cb := mock.ConfigBackend{}
   557  
   558  	expected := []string{"swarm-manager", "swarm-node"}
   559  
   560  	Install([]string{"swarm"}, &b, &cb, fakeCheckKeys)
   561  
   562  	if !reflect.DeepEqual(b.installedUnits, expected) {
   563  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits))
   564  	}
   565  }
   566  
   567  func TestUninstall(t *testing.T) {
   568  	t.Parallel()
   569  
   570  	b := backendStub{}
   571  	expected := []string{"router@3", "router@4"}
   572  
   573  	Uninstall(expected, &b)
   574  
   575  	if !reflect.DeepEqual(b.uninstalledUnits, expected) {
   576  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.uninstalledUnits))
   577  	}
   578  }
   579  
   580  func TestUninstallPlatform(t *testing.T) {
   581  	t.Parallel()
   582  
   583  	b := backendStub{}
   584  	expected := []string{"router@*", "publisher", "controller", "builder", "database",
   585  		"registry@*", "logger", "logspout", "store-volume", "store-gateway@*",
   586  		"store-metadata", "store-daemon", "store-monitor"}
   587  
   588  	Uninstall([]string{"platform"}, &b)
   589  
   590  	if !reflect.DeepEqual(b.uninstalledUnits, expected) {
   591  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.uninstalledUnits))
   592  	}
   593  }
   594  
   595  func TestUninstallStatelessPlatform(t *testing.T) {
   596  	t.Parallel()
   597  
   598  	b := backendStub{}
   599  	expected := []string{"router@*", "publisher", "controller", "builder",
   600  		"registry@*", "logspout"}
   601  
   602  	Uninstall([]string{"stateless-platform"}, &b)
   603  
   604  	if !reflect.DeepEqual(b.uninstalledUnits, expected) {
   605  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.uninstalledUnits))
   606  	}
   607  }
   608  
   609  func TestUninstallSwarm(t *testing.T) {
   610  	t.Parallel()
   611  
   612  	b := backendStub{}
   613  	expected := []string{"swarm-node", "swarm-manager"}
   614  
   615  	Uninstall([]string{"swarm"}, &b)
   616  
   617  	if !reflect.DeepEqual(b.uninstalledUnits, expected) {
   618  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.uninstalledUnits))
   619  	}
   620  }