github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/cf/commands/application/logs_test.go (about)

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