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