mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
* Preference(Timeout) int > time.Duration * Fix odo preference --help for unset examples * Preference(PushTimeout) int > time.Duration * Change set, and unset messages * Preference(RegistryCacheTime) int > time.Duration * use cobra.ExactArgs for set, and unset * mockgen * Unit tests and integration tests * Fix unit test failure * Update k8s.io/utils pkg * Philippe's review * Fix error message * Philippe's review Signed-off-by: Parthvi Vala <pvala@redhat.com> * Add minimum acceptable value for preferences accepting time.Difference type * Fix unit test failure Signed-off-by: Parthvi Vala <pvala@redhat.com> * Add migration plan with a warning, add better error message for incompatible formats Signed-off-by: Parthvi Vala <pvala@redhat.com>
269 lines
7.3 KiB
Go
269 lines
7.3 KiB
Go
package helper
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
|
|
dfutil "github.com/devfile/library/pkg/util"
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
// CreateNewContext create new empty temporary directory
|
|
func CreateNewContext() string {
|
|
directory, err := ioutil.TempDir("", "")
|
|
Expect(err).NotTo(HaveOccurred())
|
|
fmt.Fprintf(GinkgoWriter, "Created dir: %s\n", directory)
|
|
return directory
|
|
}
|
|
|
|
// DeleteDir deletes the specified path; due to Windows behaviour (for example https://github.com/redhat-developer/odo/issues/3371)
|
|
// where Windows temporarily holds a lock on files and folders, we keep trying to delete until the operation passes (or it expires)
|
|
func DeleteDir(dir string) {
|
|
attempts := 0
|
|
|
|
errorReportedAtLeastOnce := false
|
|
|
|
err := RunWithExponentialBackoff(func() error {
|
|
attempts++
|
|
|
|
fmt.Fprintf(GinkgoWriter, "Deleting dir: %s\n", dir)
|
|
err := os.RemoveAll(dir)
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
errorReportedAtLeastOnce = true
|
|
fmt.Fprintf(GinkgoWriter, "Unable to delete %s on attempt #%d, trying again...\n", dir, attempts)
|
|
|
|
return err
|
|
}, 16, 2*time.Minute)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
if errorReportedAtLeastOnce {
|
|
fmt.Fprintf(GinkgoWriter, "Successfully deleted %s after #%d attempts\n", dir, attempts)
|
|
}
|
|
}
|
|
|
|
// RunWithExponentialBackoff keeps trying to run 'fxn' until it no longer returns an error; if the function never succeeded,
|
|
// then the most recent error is returned.
|
|
func RunWithExponentialBackoff(fxn func() error, maxDelayInSeconds int, expireDuration time.Duration) error {
|
|
expireTime := time.Now().Add(expireDuration)
|
|
delayInSeconds := 1
|
|
|
|
var err error
|
|
|
|
for {
|
|
|
|
err = fxn()
|
|
|
|
if err == nil || time.Now().After(expireTime) {
|
|
break
|
|
}
|
|
|
|
delayInSeconds *= 2 // exponential backoff
|
|
if delayInSeconds > maxDelayInSeconds {
|
|
delayInSeconds = maxDelayInSeconds
|
|
}
|
|
time.Sleep(time.Duration(delayInSeconds) * time.Second)
|
|
|
|
}
|
|
return err
|
|
|
|
}
|
|
|
|
// DeleteFile deletes file
|
|
func DeleteFile(filepath string) {
|
|
fmt.Fprintf(GinkgoWriter, "Deleting file: %s\n", filepath)
|
|
err := os.Remove(filepath)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
}
|
|
|
|
// Chdir change current working dir
|
|
func Chdir(dir string) {
|
|
fmt.Fprintf(GinkgoWriter, "Setting current dir to: %s\n", dir)
|
|
err := os.Chdir(dir)
|
|
Expect(err).ShouldNot(HaveOccurred())
|
|
}
|
|
|
|
// MakeDir creates a new dir
|
|
func MakeDir(dir string) {
|
|
err := os.MkdirAll(dir, 0750)
|
|
Expect(err).ShouldNot(HaveOccurred())
|
|
}
|
|
|
|
// Getwd returns current working dir
|
|
func Getwd() string {
|
|
dir, err := os.Getwd()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
fmt.Fprintf(GinkgoWriter, "Current working dir: %s\n", dir)
|
|
return dir
|
|
}
|
|
|
|
// CopyExample copies an example from tests/examples/<binaryOrSource>/<componentName>/<exampleName> into targetDir
|
|
func CopyExample(exampleName string, targetDir string) {
|
|
// filename of this file
|
|
_, filename, _, _ := runtime.Caller(0)
|
|
// path to the examples directory
|
|
examplesDir := filepath.Join(filepath.Dir(filename), "..", "examples")
|
|
|
|
src := filepath.Join(examplesDir, exampleName)
|
|
info, err := os.Stat(src)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
err = copyDir(src, targetDir, info)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
}
|
|
|
|
func CopyManifestFile(fileName, targetDst string) {
|
|
// filename of this file
|
|
_, filename, _, _ := runtime.Caller(0)
|
|
// path to the examples directory
|
|
manifestsDir := filepath.Join(filepath.Dir(filename), "..", "examples", "manifests")
|
|
|
|
src := filepath.Join(manifestsDir, fileName)
|
|
info, err := os.Stat(src)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
err = dfutil.CopyFile(src, targetDst, info)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
}
|
|
|
|
func GetExamplePath(args ...string) string {
|
|
_, filename, _, _ := runtime.Caller(0)
|
|
path := append([]string{filepath.Dir(filename), "..", "examples"}, args...)
|
|
return filepath.Join(path...)
|
|
}
|
|
|
|
// CopyExampleDevFile copies an example devfile from tests/examples/source/devfiles/<componentName>/devfile.yaml
|
|
// into targetDst
|
|
func CopyExampleDevFile(devfilePath, targetDst string) {
|
|
// filename of this file
|
|
_, filename, _, _ := runtime.Caller(0)
|
|
// path to the examples directory
|
|
examplesDir := filepath.Join(filepath.Dir(filename), "..", "examples")
|
|
|
|
src := filepath.Join(examplesDir, devfilePath)
|
|
info, err := os.Stat(src)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
err = dfutil.CopyFile(src, targetDst, info)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
}
|
|
|
|
// FileShouldContainSubstring check if file contains subString
|
|
func FileShouldContainSubstring(file string, subString string) {
|
|
data, err := ioutil.ReadFile(file)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
Expect(string(data)).To(ContainSubstring(subString))
|
|
}
|
|
|
|
// ReplaceString replaces oldString with newString in text file
|
|
func ReplaceString(filename string, oldString string, newString string) {
|
|
fmt.Fprintf(GinkgoWriter, "Replacing \"%s\" with \"%s\" in %s\n", oldString, newString, filename)
|
|
|
|
f, err := ioutil.ReadFile(filename)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
newContent := strings.ReplaceAll(string(f), oldString, newString)
|
|
|
|
err = ioutil.WriteFile(filename, []byte(newContent), 0600)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
}
|
|
|
|
// copyDir copy one directory to the other
|
|
// this function is called recursively info should start as os.Stat(src)
|
|
func copyDir(src string, dst string, info os.FileInfo) error {
|
|
|
|
if info.IsDir() {
|
|
files, err := ioutil.ReadDir(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, file := range files {
|
|
dsrt := filepath.Join(src, file.Name())
|
|
ddst := filepath.Join(dst, file.Name())
|
|
if err := copyDir(dsrt, ddst, file); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(dst), os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
|
|
return dfutil.CopyFile(src, dst, info)
|
|
}
|
|
|
|
// CreateFileWithContent creates a file at the given path and writes the given content
|
|
// path is the path to the required file
|
|
// fileContent is the content to be written to the given file
|
|
func CreateFileWithContent(path string, fileContent string) error {
|
|
// create and open file if not exists
|
|
var file, err = os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close() // #nosec G307
|
|
// write to file
|
|
_, err = file.WriteString(fileContent)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ListFilesInDir lists all the files in the directory
|
|
// directoryName is the name of the directory
|
|
func ListFilesInDir(directoryName string) []string {
|
|
var filesInDirectory []string
|
|
files, err := ioutil.ReadDir(directoryName)
|
|
Expect(err).ShouldNot(HaveOccurred())
|
|
|
|
for _, file := range files {
|
|
filesInDirectory = append(filesInDirectory, file.Name())
|
|
}
|
|
return filesInDirectory
|
|
}
|
|
|
|
// VerifyFileExists receives a path to a file, and returns whether or not
|
|
// it points to an existing file
|
|
func VerifyFileExists(filename string) bool {
|
|
info, err := os.Stat(filename)
|
|
if os.IsNotExist(err) {
|
|
return false
|
|
}
|
|
return !info.IsDir()
|
|
}
|
|
|
|
// ReadFile reads the file from the filePath
|
|
func ReadFile(filePath string) (string, error) {
|
|
data, err := ioutil.ReadFile(filePath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(data), nil
|
|
}
|
|
|
|
// CreateSimpleFile creates a simple file
|
|
// return the file path with random string
|
|
func CreateSimpleFile(context, filePrefix, fileExtension string) (string, string) {
|
|
|
|
FilePath := filepath.Join(context, filePrefix+RandString(10)+fileExtension)
|
|
content := []byte(RandString(10))
|
|
err := ioutil.WriteFile(FilePath, content, 0600)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
return FilePath, string(content)
|
|
}
|