github.com/jasonkeene/cli@v6.14.1-0.20160816203908-ca5715166dfb+incompatible/cf/commands/application/logs_test.go (about)

     1  package application_test
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/cloudfoundry/cli/cf/api/logs"
     7  	"github.com/cloudfoundry/cli/cf/api/logs/logsfakes"
     8  	"github.com/cloudfoundry/cli/cf/commandregistry"
     9  	"github.com/cloudfoundry/cli/cf/errors"
    10  	"github.com/cloudfoundry/cli/cf/models"
    11  	"github.com/cloudfoundry/cli/cf/requirements"
    12  	"github.com/cloudfoundry/cli/cf/requirements/requirementsfakes"
    13  	testcmd "github.com/cloudfoundry/cli/testhelpers/commands"
    14  	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
    15  	testlogs "github.com/cloudfoundry/cli/testhelpers/logs"
    16  	testterm "github.com/cloudfoundry/cli/testhelpers/terminal"
    17  	"github.com/cloudfoundry/loggregatorlib/logmessage"
    18  
    19  	"github.com/cloudfoundry/cli/cf/configuration/coreconfig"
    20  	. "github.com/cloudfoundry/cli/testhelpers/matchers"
    21  	. "github.com/onsi/ginkgo"
    22  	. "github.com/onsi/gomega"
    23  )
    24  
    25  var _ = Describe("logs command", func() {
    26  	var (
    27  		ui                  *testterm.FakeUI
    28  		logsRepo            *logsfakes.FakeRepository
    29  		requirementsFactory *requirementsfakes.FakeFactory
    30  		configRepo          coreconfig.Repository
    31  		deps                commandregistry.Dependency
    32  	)
    33  
    34  	updateCommandDependency := func(pluginCall bool) {
    35  		deps.UI = ui
    36  		deps.RepoLocator = deps.RepoLocator.SetLogsRepository(logsRepo)
    37  		deps.Config = configRepo
    38  		commandregistry.Commands.SetCommand(commandregistry.Commands.FindCommand("logs").SetDependency(deps, pluginCall))
    39  	}
    40  
    41  	BeforeEach(func() {
    42  		ui = &testterm.FakeUI{}
    43  		configRepo = testconfig.NewRepositoryWithDefaults()
    44  		logsRepo = new(logsfakes.FakeRepository)
    45  		requirementsFactory = new(requirementsfakes.FakeFactory)
    46  	})
    47  
    48  	runCommand := func(args ...string) bool {
    49  		return testcmd.RunCLICommand("logs", args, requirementsFactory, updateCommandDependency, false, ui)
    50  	}
    51  
    52  	Describe("requirements", func() {
    53  		It("fails with usage when called without one argument", func() {
    54  			requirementsFactory.NewLoginRequirementReturns(requirements.Passing{})
    55  
    56  			runCommand()
    57  			Expect(ui.Outputs()).To(ContainSubstrings(
    58  				[]string{"Incorrect Usage", "Requires an argument"},
    59  			))
    60  		})
    61  
    62  		It("fails requirements when not logged in", func() {
    63  			requirementsFactory.NewLoginRequirementReturns(requirements.Failing{})
    64  
    65  			Expect(runCommand("my-app")).To(BeFalse())
    66  		})
    67  
    68  		It("fails if a space is not targeted", func() {
    69  			requirementsFactory.NewLoginRequirementReturns(requirements.Passing{})
    70  			requirementsFactory.NewTargetedSpaceRequirementReturns(requirements.Failing{Message: "not targeting space"})
    71  			Expect(runCommand("--recent", "my-app")).To(BeFalse())
    72  		})
    73  
    74  	})
    75  
    76  	Context("when logged in", func() {
    77  		var (
    78  			app models.Application
    79  		)
    80  
    81  		BeforeEach(func() {
    82  			requirementsFactory.NewLoginRequirementReturns(requirements.Passing{})
    83  			requirementsFactory.NewTargetedSpaceRequirementReturns(requirements.Passing{})
    84  
    85  			app = models.Application{}
    86  			app.Name = "my-app"
    87  			app.GUID = "my-app-guid"
    88  
    89  			currentTime := time.Now()
    90  			recentLogs := []logs.Loggable{
    91  				testlogs.NewLogMessage("Log Line 1", app.GUID, "DEA", "1", logmessage.LogMessage_ERR, currentTime),
    92  				testlogs.NewLogMessage("Log Line 2", app.GUID, "DEA", "1", logmessage.LogMessage_ERR, currentTime),
    93  			}
    94  
    95  			appLogs := []logs.Loggable{
    96  				testlogs.NewLogMessage("Log Line 1", app.GUID, "DEA", "1", logmessage.LogMessage_ERR, time.Now()),
    97  			}
    98  
    99  			applicationReq := new(requirementsfakes.FakeApplicationRequirement)
   100  			applicationReq.GetApplicationReturns(app)
   101  			requirementsFactory.NewApplicationRequirementReturns(applicationReq)
   102  
   103  			logsRepo.RecentLogsForReturns(recentLogs, nil)
   104  			logsRepo.TailLogsForStub = func(appGUID string, onConnect func(), logChan chan<- logs.Loggable, errChan chan<- error) {
   105  				onConnect()
   106  				go func() {
   107  					for _, log := range appLogs {
   108  						logChan <- log
   109  					}
   110  					close(logChan)
   111  					close(errChan)
   112  				}()
   113  			}
   114  		})
   115  
   116  		It("shows the recent logs when the --recent flag is provided", func() {
   117  			runCommand("--recent", "my-app")
   118  
   119  			Expect(app.GUID).To(Equal(logsRepo.RecentLogsForArgsForCall(0)))
   120  			Expect(ui.Outputs()).To(ContainSubstrings(
   121  				[]string{"Connected, dumping recent logs for app", "my-app", "my-org", "my-space", "my-user"},
   122  				[]string{"Log Line 1"},
   123  				[]string{"Log Line 2"},
   124  			))
   125  		})
   126  
   127  		Context("when the log messages contain format string identifiers", func() {
   128  			BeforeEach(func() {
   129  				logsRepo.RecentLogsForReturns([]logs.Loggable{
   130  					testlogs.NewLogMessage("hello%2Bworld%v", app.GUID, "DEA", "1", logmessage.LogMessage_ERR, time.Now()),
   131  				}, nil)
   132  			})
   133  
   134  			It("does not treat them as format strings", func() {
   135  				runCommand("--recent", "my-app")
   136  				Expect(ui.Outputs()).To(ContainSubstrings([]string{"hello%2Bworld%v"}))
   137  			})
   138  		})
   139  
   140  		It("tails the app's logs when no flags are given", func() {
   141  			runCommand("my-app")
   142  
   143  			appGUID, _, _, _ := logsRepo.TailLogsForArgsForCall(0)
   144  			Expect(app.GUID).To(Equal(appGUID))
   145  			Expect(ui.Outputs()).To(ContainSubstrings(
   146  				[]string{"Connected, tailing logs for app", "my-app", "my-org", "my-space", "my-user"},
   147  				[]string{"Log Line 1"},
   148  			))
   149  		})
   150  
   151  		Context("when the loggregator server has an invalid cert", func() {
   152  			Context("when the skip-ssl-validation flag is not set", func() {
   153  				It("fails and informs the user about the skip-ssl-validation flag", func() {
   154  					logsRepo.TailLogsForStub = func(appGUID string, onConnect func(), logChan chan<- logs.Loggable, errChan chan<- error) {
   155  						errChan <- errors.NewInvalidSSLCert("https://example.com", "it don't work good")
   156  					}
   157  					runCommand("my-app")
   158  
   159  					Expect(ui.Outputs()).To(ContainSubstrings(
   160  						[]string{"Received invalid SSL certificate", "https://example.com"},
   161  						[]string{"TIP"},
   162  					))
   163  				})
   164  
   165  				It("informs the user of the error when they include the --recent flag", func() {
   166  					logsRepo.RecentLogsForReturns(nil, errors.NewInvalidSSLCert("https://example.com", "how does SSL work???"))
   167  					runCommand("--recent", "my-app")
   168  
   169  					Expect(ui.Outputs()).To(ContainSubstrings(
   170  						[]string{"Received invalid SSL certificate", "https://example.com"},
   171  						[]string{"TIP"},
   172  					))
   173  				})
   174  			})
   175  		})
   176  
   177  		Context("when the loggregator server has a valid cert", func() {
   178  			It("tails logs", func() {
   179  				runCommand("my-app")
   180  				Expect(ui.Outputs()).To(ContainSubstrings(
   181  					[]string{"Connected, tailing logs for app", "my-org", "my-space", "my-user"},
   182  				))
   183  			})
   184  		})
   185  	})
   186  })