Best Rod code snippet using launcher.ProfileDir
launcher_test.go
Source:launcher_test.go  
1package main_test2import (3	"crypto/tls"4	"crypto/x509"5	"encoding/json"6	"fmt"7	"io"8	"io/ioutil"9	"net/http"10	"os"11	"os/exec"12	"path/filepath"13	"regexp"14	"runtime"15	"strings"16	"code.cloudfoundry.org/buildpackapplifecycle/containerpath"17	. "github.com/onsi/ginkgo"18	. "github.com/onsi/gomega"19	"github.com/onsi/gomega/gbytes"20	"github.com/onsi/gomega/gexec"21	"github.com/onsi/gomega/ghttp"22)23var _ = Describe("Launcher", func() {24	var extractDir string25	var appDir string26	var launcherCmd *exec.Cmd27	var session *gexec.Session28	var startCommand string29	removeFromLauncherEnv := func(keys ...string) {30		newEnv := []string{}31		for _, env := range launcherCmd.Env {32			found := false33			for _, key := range keys {34				if strings.HasPrefix(env, key) {35					found = true36					break37				}38			}39			if !found {40				newEnv = append(newEnv, env)41			}42		}43		launcherCmd.Env = newEnv44	}45	BeforeEach(func() {46		if runtime.GOOS == "windows" {47			startCommand = "cmd /C set && echo PWD=%cd% && echo running app && " + hello48		} else {49			startCommand = "env; echo running app; " + hello50		}51		var err error52		extractDir, err = ioutil.TempDir("", "vcap")53		Expect(err).NotTo(HaveOccurred())54		appDir = filepath.Join(extractDir, "app")55		err = os.MkdirAll(appDir, 0755)56		Expect(err).NotTo(HaveOccurred())57		launcherCmd = &exec.Cmd{58			Path: launcher,59			Dir:  extractDir,60			Env: append(61				os.Environ(),62				"CALLERENV=some-value",63				"TEST_CREDENTIAL_FILTER_WHITELIST=CALLERENV,DEPS_DIR,VCAP_APPLICATION,VCAP_SERVICES,A,B,C,INSTANCE_GUID,INSTANCE_INDEX,PORT,DATABASE_URL",64				"PORT=8080",65				"INSTANCE_GUID=some-instance-guid",66				"INSTANCE_INDEX=123",67				`VCAP_APPLICATION={"foo":1}`,68			),69		}70	})71	AfterEach(func() {72		Expect(os.RemoveAll(extractDir)).To(Succeed())73	})74	JustBeforeEach(func() {75		var err error76		session, err = gexec.Start(launcherCmd, GinkgoWriter, GinkgoWriter)77		Expect(err).NotTo(HaveOccurred())78	})79	var ItExecutesTheCommandWithTheRightEnvironment = func() {80		It("executes with the environment of the caller", func() {81			Eventually(session).Should(gexec.Exit(0))82			Expect(string(session.Out.Contents())).To(ContainSubstring("CALLERENV=some-value"))83		})84		It("executes the start command with $HOME as the given dir", func() {85			Eventually(session).Should(gexec.Exit(0))86			Expect(string(session.Out.Contents())).To(ContainSubstring("HOME=" + appDir))87		})88		It("changes to the app directory when running", func() {89			Eventually(session).Should(gexec.Exit(0))90			Expect(string(session.Out.Contents())).To(ContainSubstring("PWD=" + appDir))91		})92		It("executes the start command with $TMPDIR as the extract directory + /tmp", func() {93			absDir, err := filepath.Abs(filepath.Join(appDir, "..", "tmp"))94			Expect(err).NotTo(HaveOccurred())95			Eventually(session).Should(gexec.Exit(0))96			Expect(string(session.Out.Contents())).To(ContainSubstring("TMPDIR=" + absDir))97		})98		It("executes the start command with $DEPS_DIR as the extract directory + /deps", func() {99			absDir, err := filepath.Abs(filepath.Join(appDir, "..", "deps"))100			Expect(err).NotTo(HaveOccurred())101			Eventually(session).Should(gexec.Exit(0))102			Expect(string(session.Out.Contents())).To(ContainSubstring("DEPS_DIR=" + absDir))103		})104		It("munges VCAP_APPLICATION appropriately", func() {105			Eventually(session).Should(gexec.Exit(0))106			vcapAppPattern := regexp.MustCompile("VCAP_APPLICATION=(.*)")107			vcapApplicationBytes := vcapAppPattern.FindSubmatch(session.Out.Contents())[1]108			vcapApplication := map[string]interface{}{}109			err := json.Unmarshal(vcapApplicationBytes, &vcapApplication)110			Expect(err).NotTo(HaveOccurred())111			Expect(vcapApplication["host"]).To(Equal("0.0.0.0"))112			Expect(vcapApplication["port"]).To(Equal(float64(8080)))113			Expect(vcapApplication["instance_index"]).To(Equal(float64(123)))114			Expect(vcapApplication["instance_id"]).To(Equal("some-instance-guid"))115			Expect(vcapApplication["foo"]).To(Equal(float64(1)))116		})117		Context("when the given dir has .profile.d with scripts in it", func() {118			BeforeEach(func() {119				var err error120				profileDir := filepath.Join(appDir, ".profile.d")121				err = os.MkdirAll(profileDir, 0755)122				Expect(err).NotTo(HaveOccurred())123				if runtime.GOOS == "windows" {124					err = ioutil.WriteFile(filepath.Join(profileDir, "a.bat"), []byte("@echo off\necho sourcing a.bat\nset A=1\n"), 0644)125					Expect(err).NotTo(HaveOccurred())126					err = ioutil.WriteFile(filepath.Join(profileDir, "b.bat"), []byte("@echo off\necho sourcing b.bat\nset B=1\n"), 0644)127					Expect(err).NotTo(HaveOccurred())128					err = ioutil.WriteFile(filepath.Join(appDir, ".profile.bat"), []byte("@echo off\necho sourcing .profile.bat\nset C=%A%%B%\n"), 0644)129					Expect(err).NotTo(HaveOccurred())130				} else {131					err = ioutil.WriteFile(filepath.Join(profileDir, "a.sh"), []byte("echo sourcing a.sh\nexport A=1\n"), 0644)132					Expect(err).NotTo(HaveOccurred())133					err = ioutil.WriteFile(filepath.Join(profileDir, "b.sh"), []byte("echo sourcing b.sh\nexport B=1\n"), 0644)134					Expect(err).NotTo(HaveOccurred())135					err = ioutil.WriteFile(filepath.Join(appDir, ".profile"), []byte("echo sourcing .profile\nexport C=$A$B\n"), 0644)136					Expect(err).NotTo(HaveOccurred())137				}138			})139			It("sources them before sourcing .profile and before executing", func() {140				Eventually(session).Should(gexec.Exit(0))141				if runtime.GOOS == "windows" {142					Eventually(session).Should(gbytes.Say("sourcing a.bat"))143					Eventually(session).Should(gbytes.Say("sourcing b.bat"))144					Eventually(session).Should(gbytes.Say("sourcing .profile.bat"))145				} else {146					Eventually(session).Should(gbytes.Say("sourcing a.sh"))147					Eventually(session).Should(gbytes.Say("sourcing b.sh"))148					Eventually(session).Should(gbytes.Say("sourcing .profile"))149				}150				Eventually(string(session.Out.Contents())).Should(ContainSubstring("B=1"))151				Eventually(string(session.Out.Contents())).Should(ContainSubstring("C=11"))152				Eventually(string(session.Out.Contents())).Should(ContainSubstring("running app"))153			})154			Context("hello is on path", func() {155				var err error156				BeforeEach(func() {157					profileDir := filepath.Join(appDir, ".profile.d")158					err = os.MkdirAll(profileDir, 0755)159					Expect(err).NotTo(HaveOccurred())160					destDir := filepath.Join(appDir, "tmp")161					Expect(os.MkdirAll(destDir, 0777)).To(Succeed())162					Expect(copyExe(destDir, hello, "hello")).To(Succeed())163					if runtime.GOOS == "windows" {164						err = ioutil.WriteFile(filepath.Join(profileDir, "a.bat"), []byte(fmt.Sprintf("@echo off\necho sourcing a.bat\nset PATH=%%PATH%%;%s\n", destDir)), 0644)165						Expect(err).NotTo(HaveOccurred())166					} else {167						err = ioutil.WriteFile(filepath.Join(profileDir, "a.sh"), []byte(fmt.Sprintf("echo sourcing a.sh\nexport PATH=$PATH:%s\n", destDir)), 0644)168						Expect(err).NotTo(HaveOccurred())169					}170					launcherCmd.Args = []string{171						"launcher",172						appDir,173						"hello",174						`{ "start_command": "echo should not run this" }`,175					}176				})177				It("finds the app executable", func() {178					Eventually(session).Should(gexec.Exit(0))179					Expect(string(session.Out.Contents())).To(ContainSubstring("app is running"))180				})181			})182		})183		Context("when the given dir does not have .profile.d", func() {184			It("does not report errors about missing .profile.d", func() {185				Eventually(session).Should(gexec.Exit(0))186				Expect(string(session.Err.Contents())).To(BeEmpty())187			})188		})189		Context("when the given dir has an empty .profile.d", func() {190			BeforeEach(func() {191				Expect(os.MkdirAll(filepath.Join(appDir, ".profile.d"), 0755)).To(Succeed())192			})193			It("does not report errors about missing .profile.d", func() {194				Eventually(session).Should(gexec.Exit(0))195				Expect(string(session.Err.Contents())).To(BeEmpty())196			})197		})198		Context("when the given dir has ../profile.d with scripts in it", func() {199			BeforeEach(func() {200				var err error201				profileDir := filepath.Join(appDir, "..", "profile.d")202				err = os.MkdirAll(profileDir, 0755)203				Expect(err).NotTo(HaveOccurred())204				if runtime.GOOS == "windows" {205					err = ioutil.WriteFile(filepath.Join(profileDir, "a.bat"), []byte("@echo off\necho sourcing a.bat\nset A=1\n"), 0644)206					Expect(err).NotTo(HaveOccurred())207					err = ioutil.WriteFile(filepath.Join(profileDir, "b.bat"), []byte("@echo off\necho sourcing b.bat\nset B=1\n"), 0644)208					Expect(err).NotTo(HaveOccurred())209					err = os.MkdirAll(filepath.Join(appDir, ".profile.d"), 0755)210					Expect(err).NotTo(HaveOccurred())211					err = ioutil.WriteFile(filepath.Join(appDir, ".profile.d", "c.bat"), []byte("@echo off\necho sourcing c.bat\nset C=%A%%B%\n"), 0644)212					Expect(err).NotTo(HaveOccurred())213				} else {214					err = ioutil.WriteFile(filepath.Join(profileDir, "a.sh"), []byte("echo sourcing a.sh\nexport A=1\n"), 0644)215					Expect(err).NotTo(HaveOccurred())216					err = ioutil.WriteFile(filepath.Join(profileDir, "b.sh"), []byte("echo sourcing b.sh\nexport B=1\n"), 0644)217					Expect(err).NotTo(HaveOccurred())218					err = os.MkdirAll(filepath.Join(appDir, ".profile.d"), 0755)219					Expect(err).NotTo(HaveOccurred())220					err = ioutil.WriteFile(filepath.Join(appDir, ".profile.d", "c.sh"), []byte("echo sourcing c.sh\nexport C=$A$B\n"), 0644)221					Expect(err).NotTo(HaveOccurred())222				}223			})224			It("sources them before sourcing .profile.d/* and before executing", func() {225				Eventually(session).Should(gexec.Exit(0))226				if runtime.GOOS == "windows" {227					Eventually(session).Should(gbytes.Say("sourcing a.bat"))228					Eventually(session).Should(gbytes.Say("sourcing b.bat"))229					Eventually(session).Should(gbytes.Say("sourcing c.bat"))230				} else {231					Eventually(session).Should(gbytes.Say("sourcing a.sh"))232					Eventually(session).Should(gbytes.Say("sourcing b.sh"))233					Eventually(session).Should(gbytes.Say("sourcing c.sh"))234				}235				Eventually(string(session.Out.Contents())).Should(ContainSubstring("A=1"))236				Eventually(string(session.Out.Contents())).Should(ContainSubstring("B=1"))237				Eventually(string(session.Out.Contents())).Should(ContainSubstring("C=11"))238				Eventually(string(session.Out.Contents())).Should(ContainSubstring("running app"))239			})240		})241		Context("when the given dir does not have ../profile.d", func() {242			It("does not report errors about missing ../profile.d", func() {243				Eventually(session).Should(gexec.Exit(0))244				Expect(string(session.Err.Contents())).To(BeEmpty())245			})246		})247		Context("when the given dir has an empty ../profile.d", func() {248			BeforeEach(func() {249				Expect(os.MkdirAll(filepath.Join(appDir, "../profile.d"), 0755)).To(Succeed())250			})251			It("does not report errors about missing ../profile.d", func() {252				Eventually(session).Should(gexec.Exit(0))253				Expect(string(session.Err.Contents())).To(BeEmpty())254			})255		})256	}257	Context("the app executable is in vcap/app", func() {258		BeforeEach(func() {259			Expect(copyExe(appDir, hello, "hello")).To(Succeed())260			var executable string261			if runtime.GOOS == "windows" {262				executable = ".\\hello"263			} else {264				executable = "./hello"265			}266			launcherCmd.Args = []string{267				"launcher",268				appDir,269				executable,270				`{ "start_command": "echo should not run this" }`,271			}272		})273		It("finds the app executable", func() {274			Eventually(session).Should(gexec.Exit(0))275			Expect(string(session.Out.Contents())).To(ContainSubstring("app is running"))276		})277	})278	Context("the app executable path contains a space", func() {279		BeforeEach(func() {280			if runtime.GOOS != "windows" {281				Skip("file/directory names with spaces should be escaped on non-Windows OSes")282			}283			appDirWithSpaces := filepath.Join(appDir, "space dir")284			Expect(os.MkdirAll(appDirWithSpaces, 0755)).To(Succeed())285			Expect(copyExe(appDirWithSpaces, hello, "hello")).To(Succeed())286			launcherCmd.Args = []string{287				"launcher",288				appDir,289				filepath.Join(appDirWithSpaces, "hello"),290				`{ "start_command": "echo should not run this" }`,291			}292		})293		It("finds the app executable", func() {294			Eventually(session).Should(gexec.Exit(0))295			Expect(string(session.Out.Contents())).To(ContainSubstring("app is running"))296		})297	})298	Context("when the app exits", func() {299		BeforeEach(func() {300			if runtime.GOOS == "windows" {301				startCommand = "cmd.exe /C exit 26"302			} else {303				startCommand = "exit 26"304			}305			launcherCmd.Args = []string{306				"launcher",307				appDir,308				startCommand,309				`{ "start_command": "echo should not run this" }`,310			}311		})312		It("exits with the exit code of the app", func() {313			Eventually(session).Should(gexec.Exit(26))314		})315	})316	Context("when the start command starts a subprocess", func() {317		Context("the subprocess outputs to stdout", func() {318			BeforeEach(func() {319				launcherCmd.Args = []string{320					"launcher",321					appDir,322					startCommand,323					`{ "start_command": "echo should not run this" }`,324				}325			})326			It("captures stdout", func() {327				Eventually(session).Should(gexec.Exit(0))328				Expect(string(session.Out.Contents())).To(ContainSubstring("app is running"))329			})330		})331		Context("the subprocess outputs to stderr", func() {332			BeforeEach(func() {333				launcherCmd.Args = []string{334					"launcher",335					appDir,336					startCommand + " 1>&2",337					`{ "start_command": "echo should not run this" }`,338				}339			})340			It("captures stderr", func() {341				Eventually(session).Should(gexec.Exit(0))342				Expect(string(session.Err.Contents())).To(ContainSubstring("app is running"))343			})344		})345	})346	Context("when a start command is given", func() {347		BeforeEach(func() {348			launcherCmd.Args = []string{349				"launcher",350				appDir,351				startCommand,352				`{ "start_command": "echo should not run this" }`,353			}354		})355		ItExecutesTheCommandWithTheRightEnvironment()356	})357	Describe("interpolation of credhub-ref in VCAP_SERVICES", func() {358		var (359			server         *ghttp.Server360			fixturesSslDir string361			err            error362		)363		VerifyClientCerts := func() http.HandlerFunc {364			return func(w http.ResponseWriter, req *http.Request) {365				tlsConnectionState := req.TLS366				Expect(tlsConnectionState).NotTo(BeNil())367				Expect(tlsConnectionState.PeerCertificates).NotTo(BeEmpty())368				Expect(tlsConnectionState.PeerCertificates[0].Subject.CommonName).To(Equal("client"))369			}370		}371		BeforeEach(func() {372			fixturesSslDir, err = filepath.Abs(filepath.Join("..", "fixtures"))373			Expect(err).NotTo(HaveOccurred())374			server = ghttp.NewUnstartedServer()375			cert, err := tls.LoadX509KeyPair(filepath.Join(fixturesSslDir, "certs", "server.crt"), filepath.Join(fixturesSslDir, "certs", "server.key"))376			Expect(err).NotTo(HaveOccurred())377			caCerts := x509.NewCertPool()378			caCertBytes, err := ioutil.ReadFile(filepath.Join(fixturesSslDir, "cacerts", "CA.crt"))379			Expect(err).NotTo(HaveOccurred())380			Expect(caCerts.AppendCertsFromPEM(caCertBytes)).To(BeTrue())381			server.HTTPTestServer.TLS = &tls.Config{382				ClientAuth:   tls.RequireAndVerifyClientCert,383				Certificates: []tls.Certificate{cert},384				ClientCAs:    caCerts,385			}386			server.HTTPTestServer.StartTLS()387			removeFromLauncherEnv("USERPROFILE")388			launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("USERPROFILE=%s", fixturesSslDir))389			cpath := containerpath.New(fixturesSslDir)390			if cpath.For("/") == fixturesSslDir {391				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("CF_INSTANCE_CERT=%s", filepath.Join("/certs", "client.crt")))392				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("CF_INSTANCE_KEY=%s", filepath.Join("/certs", "client.key")))393				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("CF_SYSTEM_CERT_PATH=%s", "/cacerts"))394			} else {395				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("CF_INSTANCE_CERT=%s", filepath.Join(fixturesSslDir, "certs", "client.crt")))396				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("CF_INSTANCE_KEY=%s", filepath.Join(fixturesSslDir, "certs", "client.key")))397				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("CF_SYSTEM_CERT_PATH=%s", filepath.Join(fixturesSslDir, "cacerts")))398			}399			launcherCmd.Args = []string{400				"launcher",401				appDir,402				startCommand,403				"",404			}405		})406		AfterEach(func() {407			server.Close()408		})409		Context("when VCAP_SERVICES contains credhub refs", func() {410			var vcapServicesValue string411			BeforeEach(func() {412				vcapServicesValue = `{"my-server":[{"credentials":{"credhub-ref":"(//my-server/creds)"}}]}`413				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("VCAP_SERVICES=%s", vcapServicesValue))414			})415			Context("when the credhub location is passed to the launcher's platform options", func() {416				BeforeEach(func() {417					launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf(`VCAP_PLATFORM_OPTIONS={ "credhub-uri": "`+server.URL()+`"}`))418				})419				Context("when credhub successfully interpolates", func() {420					BeforeEach(func() {421						server.AppendHandlers(422							ghttp.CombineHandlers(423								ghttp.VerifyRequest("POST", "/api/v1/interpolate"),424								ghttp.VerifyBody([]byte(vcapServicesValue)),425								VerifyClientCerts(),426								ghttp.RespondWith(http.StatusOK, "INTERPOLATED_JSON"),427							))428					})429					It("updates VCAP_SERVICES with the interpolated content and runs the process without VCAP_PLATFORM_OPTIONS", func() {430						Eventually(session).Should(gexec.Exit(0))431						Eventually(session.Out).Should(gbytes.Say("VCAP_SERVICES=INTERPOLATED_JSON"))432						Eventually(session.Out).ShouldNot(gbytes.Say("VCAP_PLATFORM_OPTIONS"))433					})434				})435				Context("when credhub fails", func() {436					BeforeEach(func() {437						server.AppendHandlers(438							ghttp.CombineHandlers(439								ghttp.VerifyRequest("POST", "/api/v1/interpolate"),440								ghttp.VerifyBody([]byte(vcapServicesValue)),441								ghttp.RespondWith(http.StatusInternalServerError, "{}"),442							))443					})444					It("prints an error message", func() {445						Eventually(session).Should(gexec.Exit(3))446						Eventually(session.Err).Should(gbytes.Say("Unable to interpolate credhub references"))447					})448				})449			})450			Context("when an empty string is passed for the launcher platform options", func() {451				BeforeEach(func() {452					launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf(`VCAP_PLATFORM_OPTIONS=`))453				})454				It("does not attempt to do any credhub interpolation", func() {455					Eventually(session).Should(gexec.Exit(0))456					Eventually(string(session.Out.Contents())).Should(ContainSubstring(fmt.Sprintf(fmt.Sprintf("VCAP_SERVICES=%s", vcapServicesValue))))457					Eventually(session.Out).ShouldNot(gbytes.Say("VCAP_PLATFORM_OPTIONS"))458				})459			})460			Context("when an empty JSON is passed for the launcher platform options", func() {461				BeforeEach(func() {462					launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf(`VCAP_PLATFORM_OPTIONS={}`))463				})464				It("does not attempt to do any credhub interpolation", func() {465					Eventually(session).Should(gexec.Exit(0))466					Eventually(string(session.Out.Contents())).Should(ContainSubstring(fmt.Sprintf(fmt.Sprintf("VCAP_SERVICES=%s", vcapServicesValue))))467					Eventually(session.Out).ShouldNot(gbytes.Say("VCAP_PLATFORM_OPTIONS"))468				})469			})470			Context("when invalid JSON is passed for the launcher platform options", func() {471				BeforeEach(func() {472					launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf(`VCAP_PLATFORM_OPTIONS='{"credhub-uri":"missing quote and brace'`))473				})474				It("prints an error message", func() {475					Eventually(session).Should(gexec.Exit(3))476					Eventually(session.Err).Should(gbytes.Say("Invalid platform options"))477				})478			})479		})480		Context("VCAP_SERVICES does not have an appropriate credential", func() {481			It("DATABASE_URL is not set", func() {482				Eventually(session).Should(gexec.Exit(0))483				Expect(string(session.Out.Contents())).ToNot(ContainSubstring("DATABASE_URL="))484			})485		})486		Context("VCAP_SERVICES has an appropriate credential", func() {487			const databaseURL = "postgres://thing.com/special"488			BeforeEach(func() {489				vcapServicesValue := `{"my-server":[{"credentials":{"credhub-ref":"(//my-server/creds)"}}]}`490				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf(`VCAP_PLATFORM_OPTIONS={ "credhub-uri": "`+server.URL()+`"}`))491				launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("VCAP_SERVICES=%s", vcapServicesValue))492				server.AppendHandlers(493					ghttp.CombineHandlers(494						ghttp.VerifyRequest("POST", "/api/v1/interpolate"),495						ghttp.RespondWith(http.StatusOK, `{"my-server":[{"credentials":{"uri":"`+databaseURL+`"}}]}`),496					))497			})498			It("sets DATABASE_URL", func() {499				Eventually(session).Should(gexec.Exit(0))500				Eventually(string(session.Out.Contents())).Should(ContainSubstring(fmt.Sprintf("DATABASE_URL=%s", databaseURL)))501			})502			Context("DATABASE_URL was set before running launcher", func() {503				BeforeEach(func() {504					launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("DATABASE_URL=%s", "original content"))505				})506				It("overrides DATABASE_URL", func() {507					Eventually(session).Should(gexec.Exit(0))508					Eventually(string(session.Out.Contents())).Should(ContainSubstring(fmt.Sprintf("DATABASE_URL=%s", databaseURL)))509					Expect(string(session.Out.Contents())).ToNot(ContainSubstring("DATABASE_URL=original content"))510				})511			})512		})513	})514	Describe("setting DATABASE_URL env variable", func() {515		BeforeEach(func() {516			launcherCmd.Args = []string{517				"launcher",518				appDir,519				startCommand,520				"",521				"",522			}523		})524		Context("VCAP_SERVICES does not have an appropriate credential", func() {525			It("DATABASE_URL is not set", func() {526				Eventually(session).Should(gexec.Exit(0))527				Expect(string(session.Out.Contents())).ToNot(ContainSubstring("DATABASE_URL="))528			})529		})530		Context("VCAP_SERVICES has an appropriate credential", func() {531			Context("VCAP_SERVICES is NOT encrypted", func() {532				const databaseURL = "postgres://thing.com/special"533				BeforeEach(func() {534					vcapServicesValue := `{"my-server":[{"credentials":{"uri":"` + databaseURL + `"}}]}`535					launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("VCAP_SERVICES=%s", vcapServicesValue))536				})537				It("sets DATABASE_URL", func() {538					Eventually(session).Should(gexec.Exit(0))539					Eventually(string(session.Out.Contents())).Should(ContainSubstring(fmt.Sprintf(fmt.Sprintf("DATABASE_URL=%s", databaseURL))))540				})541				Context("DATABASE_URL was set before running builder", func() {542					BeforeEach(func() {543						launcherCmd.Env = append(launcherCmd.Env, fmt.Sprintf("DATABASE_URL=%s", "original text"))544					})545					It("overrides DATABASE_URL", func() {546						Eventually(session).Should(gexec.Exit(0))547						Eventually(string(session.Out.Contents())).Should(ContainSubstring(fmt.Sprintf(fmt.Sprintf("DATABASE_URL=%s", databaseURL))))548						Expect(string(session.Out.Contents())).ToNot(ContainSubstring("DATABASE_URL=original content"))549					})550				})551			})552		})553	})554	var ItPrintsMissingStartCommandInformation = func() {555		It("fails and reports no start command", func() {556			Eventually(session).Should(gexec.Exit(1))557			Eventually(session.Err).Should(gbytes.Say("launcher: no start command specified or detected in droplet"))558		})559	}560	Context("when no start command is given", func() {561		BeforeEach(func() {562			launcherCmd.Args = []string{563				"launcher",564				appDir,565				"",566				"",567			}568		})569		Context("when the app package does not contain staging_info.yml", func() {570			ItPrintsMissingStartCommandInformation()571		})572		Context("when the app package has a staging_info.yml", func() {573			Context("when it is missing a start command", func() {574				BeforeEach(func() {575					writeStagingInfo(extractDir, "detected_buildpack: Ruby")576				})577				ItPrintsMissingStartCommandInformation()578			})579			Context("when it contains a start command", func() {580				BeforeEach(func() {581					writeStagingInfo(extractDir, "detected_buildpack: Ruby\nstart_command: "+startCommand)582				})583				ItExecutesTheCommandWithTheRightEnvironment()584			})585			Context("when it references unresolvable types in non-essential fields", func() {586				BeforeEach(func() {587					writeStagingInfo(588						extractDir,589						"---\nbuildpack_path: !ruby/object:Pathname\n  path: /tmp/buildpacks/null-buildpack\ndetected_buildpack: \nstart_command: "+startCommand+"\n",590					)591				})592				ItExecutesTheCommandWithTheRightEnvironment()593			})594			Context("when it is not valid YAML", func() {595				BeforeEach(func() {596					writeStagingInfo(extractDir, "start_command: &ruby/object:Pathname")597				})598				It("prints an error message", func() {599					Eventually(session).Should(gexec.Exit(1))600					Eventually(session.Err).Should(gbytes.Say("Invalid staging info"))601				})602			})603		})604	})605	Context("when arguments are missing", func() {606		BeforeEach(func() {607			launcherCmd.Args = []string{608				"launcher",609				appDir,610				"env",611			}612		})613		It("fails with an indication that too few arguments were passed", func() {614			Eventually(session).Should(gexec.Exit(1))615			Eventually(session.Err).Should(gbytes.Say("launcher: received only 2 arguments\n"))616			Eventually(session.Err).Should(gbytes.Say("Usage: launcher <app-directory> <start-command> <metadata>"))617		})618	})619})620func writeStagingInfo(extractDir, stagingInfo string) {621	err := ioutil.WriteFile(filepath.Join(extractDir, "staging_info.yml"), []byte(stagingInfo), 0644)622	Expect(err).NotTo(HaveOccurred())623}624func copyExe(dstDir, src, exeName string) error {625	in, err := os.Open(src)626	if err != nil {627		return err628	}629	defer in.Close()630	dst := filepath.Join(dstDir, exeName)631	out, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE, 0755)632	if err != nil {633		return err634	}635	defer out.Close()636	_, err = io.Copy(out, in)637	cerr := out.Close()638	if err != nil {639		return err640	}641	return cerr642}...ProfileDir
Using AI Code Generation
1import (2func main() {3        c := cron.New()4        c.AddFunc("@every 1s", func() { fmt.Println("Every 1s") })5        c.AddFunc("@every 2s", func() { fmt.Println("Every 2s") })6        c.Start()7        select {}8}9import (10func main() {11        c := cron.New()12        c.AddFunc("@every 1s", func() { fmt.Println("Every 1s") })13        c.AddFunc("@every 2s", func() { fmt.Println("Every 2s") })14        c.Start()15        select {}16}17import (18func main() {19        c := cron.New()20        c.AddFunc("@every 1s", func() { fmt.Println("Every 1s") })21        c.AddFunc("@every 2s", func() { fmt.Println("Every 2s") })22        c.Start()23        select {}24}25import (26func main() {27        c := cron.New()28        c.AddFunc("@every 1s", func() { fmt.Println("Every 1s") })29        c.AddFunc("@every 2s", func() { fmt.Println("Every 2s") })30        c.Start()31        select {}32}33import (34func main() {35        c := cron.New()36        c.AddFunc("@every 1s", func() { fmt.Println("Every 1s") })37        c.AddFunc("@every 2s", func() { fmt.Println("Every 2s") })38        c.Start()39        select {}40}ProfileDir
Using AI Code Generation
1import (2func main() {3    launcher := robotgo.NewLauncher()4    dir := launcher.ProfileDir()5    fmt.Println(dir)6}7import (8func main() {9    launcher := robotgo.NewLauncher()10    version := launcher.Version()11    fmt.Println(version)12}13import (14func main() {15    launcher := robotgo.NewLauncher()16    version := launcher.Version()17    fmt.Println(version)18}19import (20func main() {21    launcher := robotgo.NewLauncher()22    version := launcher.Version()23    fmt.Println(version)24}25import (26func main() {27    launcher := robotgo.NewLauncher()28    version := launcher.Version()29    fmt.Println(version)30}31import (32func main() {33    launcher := robotgo.NewLauncher()34    version := launcher.Version()35    fmt.Println(version)36}37import (38func main() {ProfileDir
Using AI Code Generation
1import (2func main() {3	const (4	opts := []selenium.ServiceOption{5	}6	selenium.SetDebug(true)7	selenium.SetTrace(true)8	service, err := selenium.NewSeleniumService(seleniumPath, port, opts...)9	if err != nil {10	}11	defer service.Stop()12	caps := selenium.Capabilities{"browserName": "chrome"}13	caps.AddChrome(chrome.Capabilities{14		Args: []string{15		},16	})ProfileDir
Using AI Code Generation
1import (2func main() {3    ui.Main(func() {4        launcher := ui.NewLauncher()5        fmt.Println(launcher.ProfileDir())6        launcher.Destroy()7    })8}ProfileDir
Using AI Code Generation
1import (2func main() {3    launcherPath, err = exec.LookPath("launcher")4    if err != nil {5        log.Fatal(err)6    }7    launcherArgs = []string{"--profile-dir"}8    cmd = exec.Command(launcherPath, launcherArgs...)9    cmdOut, err = cmd.Output()10    if err != nil {11        log.Fatal(err)12    }13    profileDir = strings.TrimSpace(string(cmdOut))14    ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)15    defer cancel()16    launcherArgs = []string{"--profile-dir", profileDir, "--headless"}17    cmd = exec.CommandContext(ctx, launcherPath, launcherArgs...)18    err = cmd.Start()19    if err != nil {20        log.Fatal(err)21    }22    err = cmd.Wait()23    if err != nil {24        log.Fatal(err)25    }26}27import (28func main() {ProfileDir
Using AI Code Generation
1import (2func main() {3    c := cron.New()4    c.AddFunc("@every 5s", func() {5        fmt.Println("Every 5 seconds")6        err := cmd.Run()7        if err != nil {8            fmt.Println(err)9        }10    })11    c.Start()12    time.Sleep(30 * time.Second)13}14import (15func main() {16    c := cron.New()17    c.AddFunc("@every 5s", func() {18        fmt.Println("Every 5 seconds")19        err := cmd.Run()20        if err != nil {21            fmt.Println(err)22        }23    })24    c.Start()25    time.Sleep(30 * time.Second)26}27import (28func main() {29    c := cron.New()30    c.AddFunc("@every 5s", func() {31        fmt.Println("Every 5 seconds")32        err := cmd.Run()33        if err != nil {34            fmt.Println(err)35        }36    })37    c.Start()38    time.Sleep(30 * time.Second)39}ProfileDir
Using AI Code Generation
1import java.io.IOException;2public class Launcher {3    public static void main(String[] args) throws IOException {4        String profileDir = ProfileDir();5        System.out.println(profileDir);6    }7    public static String ProfileDir() throws IOException {8        String os = System.getProperty("os.name").toLowerCase();9        if (os.contains("win")) {10            return System.getenv("APPDATA");11        } else if (os.contains("mac")) {12            return System.getProperty("user.home") + "/Library/Application Support";13        } else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {14            return System.getProperty("user.home");15        } else {16            return System.getProperty("user.dir");17        }18    }19}20import java.io.IOException;21public class Launcher {22    public static void main(String[] args) throws IOException {23        String profileDir = ProfileDir();24        System.out.println(profileDir);25    }26    public static String ProfileDir() throws IOException {27        String os = System.getProperty("os.name").toLowerCase();28        if (os.contains("win")) {29            return System.getenv("APPDATA");30        } else if (os.contains("mac")) {31            return System.getProperty("user.home") + "/Library/Application Support";32        } else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {33            return System.getProperty("user.home");34        } else {35            return System.getProperty("user.dir");36        }37    }38}39import java.io.IOException;40public class Launcher {41    public static void main(String[] args) throws IOException {42        String profileDir = ProfileDir();43        System.out.println(profileDir);44    }45    public static String ProfileDir() throws IOException {46        String os = System.getProperty("os.name").toLowerCase();47        if (os.contains("win")) {48            return System.getenv("APPDATA");49        } else if (os.contains("mac")) {50            return System.getProperty("user.home") + "/Library/Application Support";51        } else if (os.contains("nix") || os.contains("nux") || os.contains("aix")) {52            return System.getProperty("user.home");53        } else {54            return System.getProperty("user.dir");55        }56    }57}ProfileDir
Using AI Code Generation
1import (2func main() {3    remote, err := godet.Connect("localhost:9222", false)4    if err != nil {5        panic(err)6    }7    if err != nil {8        panic(err)9    }10    profileDir, err := launcher.ProfileDir()11    if err != nil {12        panic(err)13    }14    fmt.Println(profileDir)15}16import (17func main() {18    remote, err := godet.Connect("localhost:9222", false)19    if err != nil {20        panic(err)21    }22    if err != nil {23        panic(err)24    }25    pathToChrome, err := launcher.PathToChrome()26    if err != nil {27        panic(err)28    }29    fmt.Println(pathToChrome)30}31import (32func main() {33    remote, err := godet.Connect("localhost:9222", false)34    if err != nil {35        panic(err)36    }ProfileDir
Using AI Code Generation
1import (2func main() {3	launch := launcher.New().Bin("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe").Headless(false).Devtools(false).Delete(true).ProfileDir("C:\\Users\\test\\AppData\\Local\\Google\\Chrome\\User Data\\Default")4	fmt.Println(launch)5	launch.Start()6	fmt.Println(launch)7}8import (9func main() {10	launch := launcher.New().Bin("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe").Headless(false).Devtools(false).Delete(true).ProfileDir("C:\\Users\\test\\AppData\\Local\\Google\\Chrome\\User Data\\Default")11	fmt.Println(launch)12	launch.Start()13	fmt.Println(launch)14}15import (16func main() {17	launch := launcher.New().Bin("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe").Headless(false).Devtools(false).Delete(true).ProfileDir("C:\\Users\\test\\AppData\\Local\\Google\\Chrome\\User Data\\Default")18	fmt.Println(launch)19	launch.Start()20	fmt.Println(launch)21}22import (23func main() {24	launch := launcher.New().Bin("C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe").Headless(false).Devtools(false).Delete(true).ProfileDir("C:\\Users\\test\\AppData\\Local\\Google\\Chrome\\User Data\\Default")25	fmt.Println(launch)26	launch.Start()27	fmt.Println(launch)28}29import (ProfileDir
Using AI Code Generation
1import (2func main() {3	launcher := exec.Command("java", "-cp", "launcher.jar", "launcher")4	profileDir, err := launcher.Output()5	if err != nil {6		fmt.Println(err)7		os.Exit(1)8	}9	profileDirPath := filepath.Join(string(profileDir), "profile")10	if err := os.MkdirAll(profileDirPath, 0777); err != nil {11		fmt.Println(err)12		os.Exit(1)13	}14	profileFile, err := os.Create(filepath.Join(profileDirPath, "profile.txt"))15	if err != nil {16		fmt.Println(err)17		os.Exit(1)18	}19	profileFile.WriteString("This is the profile file")20}21package launcher;22import java.io.File;23import java.io.IOException;24public class launcher {25	public static void main(String[] args) throws IOException {26		File profileDir = new File(System.getProperty("user.home"), ".myapp");27		profileDir.mkdir();28		System.out.print(profileDir.getAbsolutePath());29	}30}31This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for detailsLearn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
