github.com/chasestarr/deis@v1.13.5-0.20170519182049-1d9e59fbdbfc/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 TestRollingRestart(t *testing.T) {
   281  	t.Parallel()
   282  
   283  	b := backendStub{}
   284  	expected := []string{"router"}
   285  
   286  	RollingRestart("router", &b)
   287  
   288  	if !reflect.DeepEqual(b.restartedUnits, expected) {
   289  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.restartedUnits))
   290  	}
   291  }
   292  
   293  func TestUpgradePrep(t *testing.T) {
   294  	t.Parallel()
   295  
   296  	b := backendStub{}
   297  	expected := []string{"database", "registry@*", "controller", "builder", "logger", "logspout", "store-volume",
   298  		"store-gateway@*", "store-metadata", "store-daemon", "store-monitor"}
   299  
   300  	UpgradePrep(false, &b)
   301  
   302  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   303  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   304  	}
   305  }
   306  
   307  func TestStatelessUpgradePrep(t *testing.T) {
   308  	t.Parallel()
   309  
   310  	b := backendStub{}
   311  	expected := []string{"database", "registry@*", "controller", "builder", "logger", "logspout"}
   312  
   313  	UpgradePrep(true, &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 TestUpgradeTakeover(t *testing.T) {
   321  	t.Parallel()
   322  	testMock := mock.ConfigBackend{Expected: []*model.ConfigNode{{Key: "/deis/services/app1", Value: "foo", TTL: 10},
   323  		{Key: "/deis/services/app2", Value: "8000", TTL: 10}}}
   324  
   325  	b := backendStub{}
   326  	expectedRestarted := []string{"router"}
   327  	expectedStarted := []string{"publisher", "store-monitor", "store-daemon", "store-metadata",
   328  		"store-gateway@*", "store-volume", "logger", "logspout", "database", "registry@*",
   329  		"controller", "builder", "publisher", "database", "registry@*",
   330  		"controller", "builder", "publisher"}
   331  
   332  	if err := doUpgradeTakeOver(false, &b, testMock); err != nil {
   333  		t.Error(fmt.Errorf("Takeover failed: %v", err))
   334  	}
   335  
   336  	if !reflect.DeepEqual(b.restartedUnits, expectedRestarted) {
   337  		t.Error(fmt.Errorf("Expected %v, Got %v", expectedRestarted, b.restartedUnits))
   338  	}
   339  	if !reflect.DeepEqual(b.startedUnits, expectedStarted) {
   340  		t.Error(fmt.Errorf("Expected %v, Got %v", expectedStarted, b.startedUnits))
   341  	}
   342  }
   343  
   344  func TestStatelessUpgradeTakeover(t *testing.T) {
   345  	t.Parallel()
   346  	testMock := mock.ConfigBackend{Expected: []*model.ConfigNode{{Key: "/deis/services/app1", Value: "foo", TTL: 10},
   347  		{Key: "/deis/services/app2", Value: "8000", TTL: 10}}}
   348  
   349  	b := backendStub{}
   350  	expectedRestarted := []string{"router"}
   351  	expectedStarted := []string{"publisher", "logspout", "registry@*",
   352  		"controller", "builder", "publisher", "router@*", "registry@*",
   353  		"controller", "builder", "publisher"}
   354  
   355  	if err := doUpgradeTakeOver(true, &b, testMock); err != nil {
   356  		t.Error(fmt.Errorf("Takeover failed: %v", err))
   357  	}
   358  
   359  	if !reflect.DeepEqual(b.restartedUnits, expectedRestarted) {
   360  		t.Error(fmt.Errorf("Expected %v, Got %v", expectedRestarted, b.restartedUnits))
   361  	}
   362  	if !reflect.DeepEqual(b.startedUnits, expectedStarted) {
   363  		t.Error(fmt.Errorf("Expected %v, Got %v", expectedStarted, b.startedUnits))
   364  	}
   365  }
   366  
   367  func TestStop(t *testing.T) {
   368  	t.Parallel()
   369  
   370  	b := backendStub{}
   371  	expected := []string{"router@1", "router@2"}
   372  	Stop(expected, &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 TestStopPlatform(t *testing.T) {
   380  	t.Parallel()
   381  
   382  	b := backendStub{}
   383  	expected := []string{"router@*", "publisher", "controller", "builder", "database",
   384  		"registry@*", "logger", "logspout", "store-volume", "store-gateway@*",
   385  		"store-metadata", "store-daemon", "store-monitor"}
   386  	Stop([]string{"platform"}, &b)
   387  
   388  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   389  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   390  	}
   391  }
   392  
   393  func TestStopStatelessPlatform(t *testing.T) {
   394  	t.Parallel()
   395  
   396  	b := backendStub{}
   397  	expected := []string{"router@*", "publisher", "controller", "builder",
   398  		"registry@*", "logspout"}
   399  	Stop([]string{"stateless-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 TestRestart(t *testing.T) {
   407  	t.Parallel()
   408  
   409  	b := backendStub{}
   410  	expected := []string{"router@4", "router@5"}
   411  
   412  	Restart(expected, &b)
   413  
   414  	if !reflect.DeepEqual(b.stoppedUnits, expected) {
   415  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.stoppedUnits))
   416  	}
   417  	if !reflect.DeepEqual(b.startedUnits, expected) {
   418  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.startedUnits))
   419  	}
   420  }
   421  
   422  func TestSSH(t *testing.T) {
   423  	t.Parallel()
   424  
   425  	b := backendStub{}
   426  	err := SSH("controller", []string{}, &b)
   427  
   428  	if err != nil {
   429  		t.Error(err)
   430  	}
   431  }
   432  func TestSSHExec(t *testing.T) {
   433  	t.Parallel()
   434  
   435  	b := backendStub{}
   436  	err := SSH("controller", []string{"sh"}, &b)
   437  
   438  	if err != nil {
   439  		t.Error(err)
   440  	}
   441  }
   442  
   443  func TestSSHError(t *testing.T) {
   444  	t.Parallel()
   445  
   446  	b := backendStub{}
   447  	err := SSH("registry", []string{}, &b)
   448  
   449  	if err == nil {
   450  		t.Error("Error expected")
   451  	}
   452  }
   453  
   454  func TestStatus(t *testing.T) {
   455  	t.Parallel()
   456  
   457  	b := backendStub{}
   458  
   459  	if Status([]string{"controller", "builder"}, &b) != nil {
   460  		t.Error("Unexpected Error")
   461  	}
   462  }
   463  
   464  func TestStatusError(t *testing.T) {
   465  	t.Parallel()
   466  
   467  	b := backendStub{}
   468  
   469  	expected := "Test Error"
   470  	err := Status([]string{"blah"}, &b).Error()
   471  
   472  	if err != expected {
   473  		t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err))
   474  	}
   475  }
   476  
   477  func TestJournal(t *testing.T) {
   478  	t.Parallel()
   479  
   480  	b := backendStub{}
   481  
   482  	if Journal([]string{"controller", "builder"}, &b) != nil {
   483  		t.Error("Unexpected Error")
   484  	}
   485  }
   486  
   487  func TestJournalError(t *testing.T) {
   488  	t.Parallel()
   489  
   490  	b := backendStub{}
   491  
   492  	expected := "Test Error"
   493  	err := Journal([]string{"blah"}, &b).Error()
   494  
   495  	if err != expected {
   496  		t.Error(fmt.Errorf("Expected '%v', Got '%v'", expected, err))
   497  	}
   498  }
   499  
   500  func TestInstall(t *testing.T) {
   501  	t.Parallel()
   502  
   503  	b := backendStub{}
   504  	cb := mock.ConfigBackend{}
   505  
   506  	expected := []string{"router@1", "router@2"}
   507  
   508  	Install(expected, &b, &cb, fakeCheckKeys)
   509  
   510  	if !reflect.DeepEqual(b.installedUnits, expected) {
   511  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits))
   512  	}
   513  }
   514  
   515  func TestInstallPlatform(t *testing.T) {
   516  	t.Parallel()
   517  
   518  	b := backendStub{}
   519  	cb := mock.ConfigBackend{}
   520  
   521  	expected := []string{"store-daemon", "store-monitor", "store-metadata", "store-volume",
   522  		"store-gateway@1", "logger", "logspout", "database", "registry@1",
   523  		"controller", "builder", "publisher", "router@1", "router@2", "router@3"}
   524  
   525  	Install([]string{"platform"}, &b, &cb, fakeCheckKeys)
   526  
   527  	if !reflect.DeepEqual(b.installedUnits, expected) {
   528  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits))
   529  	}
   530  }
   531  
   532  func TestInstallPlatformWithCustomRouterMeshSize(t *testing.T) {
   533  	t.Parallel()
   534  
   535  	b := backendStub{}
   536  	cb := mock.ConfigBackend{}
   537  
   538  	expected := []string{"store-daemon", "store-monitor", "store-metadata", "store-volume",
   539  		"store-gateway@1", "logger", "logspout", "database", "registry@1",
   540  		"controller", "builder", "publisher", "router@1", "router@2", "router@3", "router@4", "router@5"}
   541  	RouterMeshSize = 5
   542  
   543  	Install([]string{"platform"}, &b, &cb, fakeCheckKeys)
   544  	RouterMeshSize = DefaultRouterMeshSize
   545  
   546  	if !reflect.DeepEqual(b.installedUnits, expected) {
   547  		t.Error(fmt.Errorf("Expected %v, Got %v", expected, b.installedUnits))
   548  	}
   549  }
   550  
   551  func TestInstallStatelessPlatform(t *testing.T) {
   552  	t.Parallel()
   553  
   554  	b := backendStub{}
   555  	cb := mock.ConfigBackend{}
   556  
   557  	expected := []string{"logger", "logspout", "registry@1",
   558  		"controller", "builder", "publisher", "router@1", "router@2", "router@3"}
   559  
   560  	Install([]string{"stateless-platform"}, &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  }