github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/integration/helpers/app.go (about)

     1  package helpers
     2  
     3  import (
     4  	"archive/zip"
     5  	"fmt"
     6  	"github.com/onsi/gomega/gbytes"
     7  	"io"
     8  	"io/ioutil"
     9  	"math/rand"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  
    14  	. "github.com/onsi/gomega"
    15  	. "github.com/onsi/gomega/gexec"
    16  	"gopkg.in/yaml.v2"
    17  )
    18  
    19  // WithHelloWorldApp creates a simple application to use with your CLI command
    20  // (typically CF Push). When pushing, be aware of specifying '-b
    21  // staticfile_buildpack" so that your app will correctly start up with the
    22  // proper buildpack.
    23  func WithHelloWorldApp(f func(dir string)) {
    24  	dir, err := ioutil.TempDir("", "simple-app")
    25  	Expect(err).ToNot(HaveOccurred())
    26  	defer os.RemoveAll(dir)
    27  
    28  	tempfile := filepath.Join(dir, "index.html")
    29  	err = ioutil.WriteFile(tempfile, []byte(fmt.Sprintf("hello world %d", rand.Int())), 0666)
    30  	Expect(err).ToNot(HaveOccurred())
    31  
    32  	err = ioutil.WriteFile(filepath.Join(dir, "Staticfile"), nil, 0666)
    33  	Expect(err).ToNot(HaveOccurred())
    34  
    35  	f(dir)
    36  }
    37  
    38  // WithMultiEndpointApp creates a simple application to use with your CLI command
    39  // (typically CF Push). It has multiple endpoints which are helpful when testing
    40  // http healthchecks
    41  func WithMultiEndpointApp(f func(dir string)) {
    42  	dir, err := ioutil.TempDir("", "simple-app")
    43  	Expect(err).ToNot(HaveOccurred())
    44  	defer os.RemoveAll(dir)
    45  
    46  	tempfile := filepath.Join(dir, "index.html")
    47  	err = ioutil.WriteFile(tempfile, []byte(fmt.Sprintf("hello world %d", rand.Int())), 0666)
    48  	Expect(err).ToNot(HaveOccurred())
    49  
    50  	tempfile = filepath.Join(dir, "other_endpoint.html")
    51  	err = ioutil.WriteFile(tempfile, []byte("other endpoint"), 0666)
    52  	Expect(err).ToNot(HaveOccurred())
    53  
    54  	tempfile = filepath.Join(dir, "third_endpoint.html")
    55  	err = ioutil.WriteFile(tempfile, []byte("third endpoint"), 0666)
    56  	Expect(err).ToNot(HaveOccurred())
    57  
    58  	err = ioutil.WriteFile(filepath.Join(dir, "Staticfile"), nil, 0666)
    59  	Expect(err).ToNot(HaveOccurred())
    60  
    61  	f(dir)
    62  }
    63  
    64  // WithNoResourceMatchedApp creates a simple application to use with your CLI
    65  // command (typically CF Push). When pushing, be aware of specifying '-b
    66  // staticfile_buildpack" so that your app will correctly start up with the
    67  // proper buildpack.
    68  func WithNoResourceMatchedApp(f func(dir string)) {
    69  	dir, err := ioutil.TempDir("", "simple-app")
    70  	Expect(err).ToNot(HaveOccurred())
    71  	defer os.RemoveAll(dir)
    72  
    73  	tempfile := filepath.Join(dir, "index.html")
    74  
    75  	err = ioutil.WriteFile(tempfile, []byte(fmt.Sprintf("hello world %s", strings.Repeat("a", 65*1024))), 0666)
    76  	Expect(err).ToNot(HaveOccurred())
    77  
    78  	f(dir)
    79  }
    80  
    81  // WithMultiBuildpackApp creates a multi-buildpack application to use with the CF push command.
    82  func WithMultiBuildpackApp(f func(dir string)) {
    83  	f("../../assets/go_calls_ruby")
    84  }
    85  
    86  // WithProcfileApp creates an application to use with your CLI command
    87  // that contains Procfile defining web and worker processes.
    88  func WithProcfileApp(f func(dir string)) {
    89  	dir, err := ioutil.TempDir("", "simple-ruby-app")
    90  	Expect(err).ToNot(HaveOccurred())
    91  	defer os.RemoveAll(dir)
    92  
    93  	err = ioutil.WriteFile(filepath.Join(dir, "Procfile"), []byte(`---
    94  web: ruby -run -e httpd . -p $PORT
    95  console: bundle exec irb`,
    96  	), 0666)
    97  	Expect(err).ToNot(HaveOccurred())
    98  
    99  	err = ioutil.WriteFile(filepath.Join(dir, "Gemfile"), nil, 0666)
   100  	Expect(err).ToNot(HaveOccurred())
   101  
   102  	err = ioutil.WriteFile(filepath.Join(dir, "Gemfile.lock"), []byte(`
   103  GEM
   104    specs:
   105  
   106  PLATFORMS
   107    ruby
   108  
   109  DEPENDENCIES
   110  
   111  BUNDLED WITH
   112     1.15.0
   113  	`), 0666)
   114  	Expect(err).ToNot(HaveOccurred())
   115  
   116  	f(dir)
   117  }
   118  
   119  // WithCrashingApp creates an application to use with your CLI command
   120  // that will not successfully start its `web` process
   121  func WithCrashingApp(f func(dir string)) {
   122  	dir, err := ioutil.TempDir("", "crashing-ruby-app")
   123  	Expect(err).ToNot(HaveOccurred())
   124  	defer os.RemoveAll(dir)
   125  
   126  	err = ioutil.WriteFile(filepath.Join(dir, "Procfile"), []byte(`---
   127  web: bogus bogus`,
   128  	), 0666)
   129  	Expect(err).ToNot(HaveOccurred())
   130  
   131  	err = ioutil.WriteFile(filepath.Join(dir, "Gemfile"), nil, 0666)
   132  	Expect(err).ToNot(HaveOccurred())
   133  
   134  	err = ioutil.WriteFile(filepath.Join(dir, "Gemfile.lock"), []byte(`
   135  GEM
   136    specs:
   137  
   138  PLATFORMS
   139    ruby
   140  
   141  DEPENDENCIES
   142  
   143  BUNDLED WITH
   144     1.15.0
   145  	`), 0666)
   146  	Expect(err).ToNot(HaveOccurred())
   147  
   148  	f(dir)
   149  }
   150  
   151  // WithBananaPantsApp creates a simple application to use with your CLI command
   152  // (typically CF Push). When pushing, be aware of specifying '-b
   153  // staticfile_buildpack" so that your app will correctly start up with the
   154  // proper buildpack.
   155  func WithBananaPantsApp(f func(dir string)) {
   156  	dir, err := ioutil.TempDir("", "simple-app")
   157  	Expect(err).ToNot(HaveOccurred())
   158  	defer os.RemoveAll(dir)
   159  
   160  	tempfile := filepath.Join(dir, "index.html")
   161  	err = ioutil.WriteFile(tempfile, []byte("Banana Pants"), 0666)
   162  	Expect(err).ToNot(HaveOccurred())
   163  
   164  	err = ioutil.WriteFile(filepath.Join(dir, "Staticfile"), nil, 0666)
   165  	Expect(err).ToNot(HaveOccurred())
   166  
   167  	f(dir)
   168  }
   169  
   170  // AppGUID returns the GUID for an app in the currently targeted space.
   171  func AppGUID(appName string) string {
   172  	session := CF("app", appName, "--guid")
   173  	Eventually(session).Should(Exit(0))
   174  	return strings.TrimSpace(string(session.Out.Contents()))
   175  }
   176  
   177  func AppJSON(appName string) string {
   178  	appGUID := AppGUID(appName)
   179  	session := CF("curl", fmt.Sprintf("/v3/apps/%s", appGUID))
   180  	Eventually(session).Should(Exit(0))
   181  	return strings.TrimSpace(string(session.Out.Contents()))
   182  }
   183  
   184  // WriteManifest will write out a YAML manifest file at the specified path.
   185  func WriteManifest(path string, manifest map[string]interface{}) {
   186  	body, err := yaml.Marshal(manifest)
   187  	Expect(err).ToNot(HaveOccurred())
   188  	err = ioutil.WriteFile(path, body, 0666)
   189  	Expect(err).ToNot(HaveOccurred())
   190  }
   191  
   192  // Zipit zips the source into a .zip file in the target dir
   193  func Zipit(source, target, prefix string) error {
   194  	// Thanks to Svett Ralchev
   195  	// http://blog.ralch.com/tutorial/golang-working-with-zip/
   196  
   197  	zipfile, err := os.Create(target)
   198  	if err != nil {
   199  		return err
   200  	}
   201  	defer zipfile.Close()
   202  
   203  	if prefix != "" {
   204  		_, err = io.WriteString(zipfile, prefix)
   205  		if err != nil {
   206  			return err
   207  		}
   208  	}
   209  
   210  	archive := zip.NewWriter(zipfile)
   211  	defer archive.Close()
   212  
   213  	err = filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
   214  		if err != nil {
   215  			return err
   216  		}
   217  
   218  		if path == source {
   219  			return nil
   220  		}
   221  
   222  		header, err := zip.FileInfoHeader(info)
   223  		if err != nil {
   224  			return err
   225  		}
   226  		header.Name, err = filepath.Rel(source, path)
   227  		if err != nil {
   228  			return err
   229  		}
   230  
   231  		header.Name = filepath.ToSlash(header.Name)
   232  
   233  		if info.IsDir() {
   234  			header.Name += "/"
   235  			header.SetMode(0755)
   236  		} else {
   237  			header.Method = zip.Deflate
   238  			header.SetMode(0744)
   239  		}
   240  
   241  		writer, err := archive.CreateHeader(header)
   242  		if err != nil {
   243  			return err
   244  		}
   245  
   246  		if info.IsDir() {
   247  			return nil
   248  		}
   249  
   250  		file, err := os.Open(path)
   251  		if err != nil {
   252  			return err
   253  		}
   254  		defer file.Close()
   255  
   256  		_, err = io.Copy(writer, file)
   257  		return err
   258  	})
   259  
   260  	return err
   261  }
   262  
   263  func ConfirmStagingLogs(session *Session) {
   264  	Eventually(session).Should(gbytes.Say(`(?i)Creating container|Successfully created container|Staging\.\.\.|Staging process started \.\.\.|Staging Complete|Exit status 0|Uploading droplet\.\.\.|Uploading complete`))
   265  }