mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
* Add unit test highliging the issue * Fix 'delete' unit tests * Pass the filesystem object where it is relevant * Add a way for CLI commands to indicate whether of not they require a valid Devfile For the 'analyze' command, this is not required, so Devfile parsing will be ignored completely. * Make the fake filesystem return an absolute current dir Otherwise, some code will assume it is relative, and try to prepend the current physical directory
2878 lines
69 KiB
Go
2878 lines
69 KiB
Go
package util
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"os/user"
|
|
"path/filepath"
|
|
"regexp"
|
|
"runtime"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
|
dfutil "github.com/devfile/library/v2/pkg/util"
|
|
"github.com/go-git/go-git/v5"
|
|
"github.com/go-git/go-git/v5/config"
|
|
"github.com/google/go-cmp/cmp"
|
|
corev1 "k8s.io/api/core/v1"
|
|
|
|
"github.com/redhat-developer/odo/pkg/testingutil/filesystem"
|
|
)
|
|
|
|
// TODO(feloy) Move tests to devfile library
|
|
|
|
func TestNamespaceOpenShiftObject(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
testName string
|
|
componentName string
|
|
applicationName string
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
testName: "Test namespacing",
|
|
componentName: "foo",
|
|
applicationName: "bar",
|
|
want: "foo-bar",
|
|
},
|
|
{
|
|
testName: "Blank applicationName with namespacing",
|
|
componentName: "foo",
|
|
applicationName: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
testName: "Blank componentName with namespacing",
|
|
componentName: "",
|
|
applicationName: "bar",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
// Test that it "joins"
|
|
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.testName)
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
name, err := dfutil.NamespaceOpenShiftObject(tt.componentName, tt.applicationName)
|
|
|
|
if tt.wantErr && err == nil {
|
|
t.Errorf("Expected an error, got success")
|
|
} else if tt.wantErr == false && err != nil {
|
|
t.Errorf("Error with namespacing: %s", err)
|
|
}
|
|
|
|
if tt.want != name {
|
|
t.Errorf("Expected %s, got %s", tt.want, name)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestExtractComponentType(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
testName string
|
|
componentType string
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
testName: "Test namespacing and versioning",
|
|
componentType: "myproject/foo:3.5",
|
|
want: "foo",
|
|
},
|
|
{
|
|
testName: "Test versioning",
|
|
componentType: "foo:3.5",
|
|
want: "foo",
|
|
},
|
|
{
|
|
testName: "Test plain component type",
|
|
componentType: "foo",
|
|
want: "foo",
|
|
},
|
|
}
|
|
|
|
// Test that it "joins"
|
|
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.testName)
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
name := dfutil.ExtractComponentType(tt.componentType)
|
|
if tt.want != name {
|
|
t.Errorf("Expected %s, got %s", tt.want, name)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestGetDNS1123Name(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
testName string
|
|
param string
|
|
want string
|
|
}{
|
|
{
|
|
testName: "Case 1: Test get DNS-1123 name for namespace and version qualified imagestream",
|
|
param: "myproject/foo:3.5",
|
|
want: "myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 2: Test get DNS-1123 name for doubly hyphenated string",
|
|
param: "nodejs--myproject-foo-3.5",
|
|
want: "nodejs-myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 3: Test get DNS-1123 name for string starting with underscore",
|
|
param: "_nodejs--myproject-foo-3.5",
|
|
want: "nodejs-myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 4: Test get DNS-1123 name for string ending with underscore",
|
|
param: "nodejs--myproject-foo-3.5_",
|
|
want: "nodejs-myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 5: Test get DNS-1123 name for string having multiple non alpha-numeric chars as prefix",
|
|
param: "_#*nodejs--myproject-foo-3.5",
|
|
want: "nodejs-myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 6: Test get DNS-1123 name for string having multiple non alpha-numeric chars as suffix",
|
|
param: "nodejs--myproject-foo-3.5=_@",
|
|
want: "nodejs-myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 7: Test get DNS-1123 name for string having with multiple non alpha-numeric chars as prefix and suffix",
|
|
param: " _#*nodejs--myproject-foo-3.5=_@ ",
|
|
want: "nodejs-myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 8: Test get DNS-1123 should remove invalid chars",
|
|
param: "myproject/$foo@@:3.5",
|
|
want: "myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 9: Test get DNS-1123 should remove invalid chars with sufix and prefix",
|
|
param: "54myproject/$foo@@:3.5",
|
|
want: "myproject-foo-3-5",
|
|
},
|
|
{
|
|
testName: "Case 9: Test get DNS-1123 should add x as a prefix for all numerics",
|
|
param: "54453443",
|
|
want: "x54453443",
|
|
},
|
|
}
|
|
|
|
// Test that it "joins"
|
|
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.testName)
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
name := GetDNS1123Name(tt.param)
|
|
if tt.want != name {
|
|
t.Errorf("Expected %s, got %s", tt.want, name)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestGetRandomName(t *testing.T) {
|
|
type args struct {
|
|
prefix string
|
|
existList []string
|
|
}
|
|
tests := []struct {
|
|
testName string
|
|
args args
|
|
// want is regexp if expectConflictResolution is true else its a full name
|
|
want string
|
|
}{
|
|
{
|
|
testName: "Case: Optional suffix passed and prefix-suffix as a name is not already used",
|
|
args: args{
|
|
prefix: "odo",
|
|
existList: []string{
|
|
"odo-auth",
|
|
"odo-pqrs",
|
|
},
|
|
},
|
|
want: "odo-[a-z]{4}",
|
|
},
|
|
{
|
|
testName: "Case: Optional suffix passed and prefix-suffix as a name is already used",
|
|
args: args{
|
|
prefix: "nodejs-ex-nodejs",
|
|
existList: []string{
|
|
"nodejs-ex-nodejs-yvrp",
|
|
"nodejs-ex-nodejs-abcd",
|
|
},
|
|
},
|
|
want: "nodejs-ex-nodejs-[a-z]{4}",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.testName)
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
name, err := dfutil.GetRandomName(tt.args.prefix, -1, tt.args.existList, 3)
|
|
if err != nil {
|
|
t.Errorf("failed to generate a random name. Error %v", err)
|
|
}
|
|
|
|
r, _ := regexp.Compile(tt.want)
|
|
match := r.MatchString(name)
|
|
if !match {
|
|
t.Errorf("Received name %s which does not match %s", name, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTruncateString(t *testing.T) {
|
|
tests := []struct {
|
|
testName string
|
|
str string
|
|
strLength int
|
|
appendStr bool
|
|
appendArr []string
|
|
want string
|
|
}{
|
|
{
|
|
testName: "Case: Truncate string to greater length",
|
|
str: "qw",
|
|
strLength: 4,
|
|
appendStr: false,
|
|
want: "qw",
|
|
},
|
|
{
|
|
testName: "Case: Truncate string to lesser length",
|
|
str: "rtyu",
|
|
strLength: 3,
|
|
appendStr: false,
|
|
want: "rty",
|
|
},
|
|
{
|
|
testName: "Case: Truncate string to -1 length",
|
|
str: "Odo",
|
|
strLength: -1,
|
|
appendStr: false,
|
|
want: "Odo",
|
|
},
|
|
{
|
|
testName: "Case: Trunicate string with 3 dots appended",
|
|
str: "rtyu",
|
|
strLength: 3,
|
|
appendStr: true,
|
|
appendArr: []string{"..."},
|
|
want: "rty...",
|
|
},
|
|
{
|
|
testName: "Case: Appends multiple if multiple args are provided",
|
|
str: "rtyu",
|
|
strLength: 3,
|
|
appendStr: true,
|
|
appendArr: []string{".", ".", "."},
|
|
want: "rty...",
|
|
},
|
|
{
|
|
testName: "Case: Does not append if length is lesser than max length",
|
|
str: "qw",
|
|
strLength: 4,
|
|
appendStr: true,
|
|
appendArr: []string{"..."},
|
|
want: "qw",
|
|
},
|
|
{
|
|
testName: "Case: Does not append if maxlength is -1",
|
|
str: "rtyu",
|
|
strLength: -1,
|
|
appendStr: true,
|
|
appendArr: []string{"..."},
|
|
want: "rtyu",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.testName)
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
var receivedStr string
|
|
if tt.appendStr {
|
|
receivedStr = TruncateString(tt.str, tt.strLength, tt.appendArr...)
|
|
} else {
|
|
receivedStr = TruncateString(tt.str, tt.strLength)
|
|
}
|
|
if tt.want != receivedStr {
|
|
t.Errorf("Truncated string %s is not same as %s", receivedStr, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGenerateRandomString(t *testing.T) {
|
|
tests := []struct {
|
|
testName string
|
|
strLength int
|
|
}{
|
|
{
|
|
testName: "Case: Generate random string of length 4",
|
|
strLength: 4,
|
|
},
|
|
{
|
|
testName: "Case: Generate random string of length 3",
|
|
strLength: 3,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.testName)
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
name := dfutil.GenerateRandomString(tt.strLength)
|
|
r, _ := regexp.Compile(fmt.Sprintf("[a-z]{%d}", tt.strLength))
|
|
match := r.MatchString(name)
|
|
if !match {
|
|
t.Errorf("Randomly generated string %s which does not match regexp %s", name, fmt.Sprintf("[a-z]{%d}", tt.strLength))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetAbsPath(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
path string
|
|
absPath string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Valid abs path resolution of `~`",
|
|
path: "~",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Valid abs path resolution of `.`",
|
|
path: ".",
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.name)
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
switch tt.path {
|
|
case "~":
|
|
if len(customHomeDir) > 0 {
|
|
tt.absPath = customHomeDir
|
|
} else {
|
|
usr, err := user.Current()
|
|
if err != nil {
|
|
t.Errorf("Failed to get absolute path corresponding to `~`. Error %v", err)
|
|
return
|
|
}
|
|
tt.absPath = usr.HomeDir
|
|
}
|
|
|
|
case ".":
|
|
absPath, err := os.Getwd()
|
|
if err != nil {
|
|
t.Errorf("Failed to get absolute path corresponding to `.`. Error %v", err)
|
|
return
|
|
}
|
|
tt.absPath = absPath
|
|
}
|
|
result, err := dfutil.GetAbsPath(tt.path)
|
|
if result != tt.absPath {
|
|
t.Errorf("Expected %v, got %v", tt.absPath, result)
|
|
}
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("Expected error: %v got error %v", tt.wantErr, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCheckPathExists(t *testing.T) {
|
|
tests := []struct {
|
|
fsProvider func() (filesystem.Filesystem, error)
|
|
fileName string
|
|
wantBool bool
|
|
}{
|
|
{
|
|
fsProvider: func() (filesystem.Filesystem, error) {
|
|
fakeFs := filesystem.NewFakeFs()
|
|
_, err := fakeFs.Create("my-file")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return fakeFs, nil
|
|
},
|
|
fileName: "my-file",
|
|
wantBool: true,
|
|
},
|
|
{
|
|
fsProvider: func() (filesystem.Filesystem, error) {
|
|
return filesystem.NewFakeFs(), nil
|
|
},
|
|
fileName: "some-file-blah",
|
|
wantBool: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
fsys, err := tt.fsProvider()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
exists := CheckPathExists(fsys, tt.fileName)
|
|
if tt.wantBool != exists {
|
|
t.Errorf("the expected value of TestCheckPathExists function is different : %v, got: %v", tt.wantBool, exists)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetHostWithPort(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
inputURL string
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
inputURL: "https://example.com",
|
|
want: "example.com:443",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
inputURL: "https://example.com:8443",
|
|
want: "example.com:8443",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
inputURL: "http://example.com",
|
|
want: "example.com:80",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
inputURL: "notexisting://example.com",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
inputURL: "http://127.0.0.1",
|
|
want: "127.0.0.1:80",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
inputURL: "example.com:1234",
|
|
want: "",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(fmt.Sprintf("Testing inputURL: %s", tt.inputURL), func(t *testing.T) {
|
|
got, err := dfutil.GetHostWithPort(tt.inputURL)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("getHostWithPort() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("getHostWithPort() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// MakeFileWithContent creates file with a given name in the given directory and writes the content to it
|
|
// dir is the name of the directory
|
|
// fileName is the name of the file to be created
|
|
// content is the string to be written to the file
|
|
func MakeFileWithContent(dir string, fileName string, content string) error {
|
|
file, err := os.Create(dir + string(os.PathSeparator) + fileName)
|
|
if err != nil {
|
|
return fmt.Errorf("error while creating file: %w", err)
|
|
}
|
|
defer file.Close()
|
|
_, err = file.WriteString(content)
|
|
if err != nil {
|
|
return fmt.Errorf("error while writing to file: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RemoveContentsFromDir removes content from the given directory
|
|
// dir is the name of the directory
|
|
func RemoveContentsFromDir(dir string) error {
|
|
files, err := filepath.Glob(filepath.Join(dir, "*"))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, file := range files {
|
|
err = os.RemoveAll(file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestGetIgnoreRulesFromDirectory(t *testing.T) {
|
|
testDir := t.TempDir()
|
|
tests := []struct {
|
|
name string
|
|
directoryName string
|
|
filesToCreate []string
|
|
rulesOnGitIgnore string
|
|
rulesOnOdoIgnore string
|
|
wantRules []string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "test case 1: no odoignore and no gitignore",
|
|
directoryName: testDir,
|
|
filesToCreate: []string{""},
|
|
rulesOnGitIgnore: "",
|
|
rulesOnOdoIgnore: "",
|
|
wantRules: []string{".git"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "test case 2: no odoignore but gitignore exists with no rules",
|
|
directoryName: testDir,
|
|
filesToCreate: []string{DotGitIgnoreFile},
|
|
rulesOnGitIgnore: "",
|
|
rulesOnOdoIgnore: "",
|
|
wantRules: []string{".git"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "test case 3: no odoignore but gitignore exists with rules",
|
|
directoryName: testDir,
|
|
filesToCreate: []string{DotGitIgnoreFile},
|
|
rulesOnGitIgnore: "*.js\n\n/openshift/**/*.json\n/tests",
|
|
rulesOnOdoIgnore: "",
|
|
wantRules: []string{".git", "*.js", "/openshift/**/*.json", "/tests"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "test case 4: odoignore exists with no rules",
|
|
directoryName: testDir,
|
|
filesToCreate: []string{".odoignore"},
|
|
rulesOnGitIgnore: "",
|
|
rulesOnOdoIgnore: "",
|
|
wantRules: []string{".git"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "test case 5: odoignore exists with rules",
|
|
directoryName: testDir,
|
|
filesToCreate: []string{".odoignore"},
|
|
rulesOnGitIgnore: "",
|
|
rulesOnOdoIgnore: "*.json\n\n/openshift/**/*.js",
|
|
wantRules: []string{".git", "*.json", "/openshift/**/*.js"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "test case 6: odoignore and gitignore both exists with rules",
|
|
directoryName: testDir,
|
|
filesToCreate: []string{DotGitIgnoreFile, ".odoignore"},
|
|
rulesOnGitIgnore: "/tests",
|
|
rulesOnOdoIgnore: "*.json\n\n/openshift/**/*.js",
|
|
wantRules: []string{".git", "*.json", "/openshift/**/*.js"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "test case 7: no odoignore but gitignore exists with rules and comments",
|
|
directoryName: testDir,
|
|
filesToCreate: []string{DotGitIgnoreFile},
|
|
rulesOnGitIgnore: "*.js\n\n/openshift/**/*.json\n\n\n#/tests",
|
|
rulesOnOdoIgnore: "",
|
|
wantRules: []string{".git", "*.js", "/openshift/**/*.json"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "test case 8: odoignore exists exists with rules and comments",
|
|
directoryName: testDir,
|
|
filesToCreate: []string{".odoignore"},
|
|
rulesOnOdoIgnore: "*.js\n\n\n/openshift/**/*.json\n\n\n#/tests\n/bin",
|
|
rulesOnGitIgnore: "",
|
|
wantRules: []string{".git", "*.js", "/openshift/**/*.json", "/bin"},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
for _, fileName := range tt.filesToCreate {
|
|
var err error
|
|
if fileName == DotGitIgnoreFile {
|
|
err = MakeFileWithContent(testDir, fileName, tt.rulesOnGitIgnore)
|
|
} else if fileName == ".odoignore" {
|
|
err = MakeFileWithContent(testDir, fileName, tt.rulesOnOdoIgnore)
|
|
}
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
gotRules, err := dfutil.GetIgnoreRulesFromDirectory(testDir)
|
|
|
|
if err == nil && !tt.wantErr {
|
|
if diff := cmp.Diff(tt.wantRules, gotRules); diff != "" {
|
|
t.Errorf("dfutil.GetIgnoreRulesFromDirectory() wantRules mismatch (-want +got):\n%s", diff)
|
|
}
|
|
} else if err == nil && tt.wantErr {
|
|
t.Error("error was expected, but no error was returned")
|
|
} else if err != nil && !tt.wantErr {
|
|
t.Errorf("test failed, no error was expected, but got unexpected error: %s", err)
|
|
}
|
|
err = RemoveContentsFromDir(testDir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetAbsGlobExps(t *testing.T) {
|
|
tests := []struct {
|
|
testName string
|
|
directoryName string
|
|
inputRelativeGlobExps []string
|
|
expectedGlobExps []string
|
|
}{
|
|
{
|
|
testName: "test case 1: with a filename",
|
|
directoryName: "/home/redhat/nodejs-ex/",
|
|
inputRelativeGlobExps: []string{
|
|
"example.txt",
|
|
},
|
|
expectedGlobExps: []string{
|
|
"/home/redhat/nodejs-ex/example.txt",
|
|
},
|
|
},
|
|
{
|
|
testName: "test case 2: with a folder name",
|
|
directoryName: "/home/redhat/nodejs-ex/",
|
|
inputRelativeGlobExps: []string{
|
|
"example/",
|
|
},
|
|
expectedGlobExps: []string{
|
|
"/home/redhat/nodejs-ex/example",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
resultExps := dfutil.GetAbsGlobExps(tt.directoryName, tt.inputRelativeGlobExps)
|
|
if runtime.GOOS == "windows" {
|
|
for index, element := range resultExps {
|
|
resultExps[index] = filepath.ToSlash(element)
|
|
}
|
|
}
|
|
|
|
if diff := cmp.Diff(tt.expectedGlobExps, resultExps); diff != "" {
|
|
t.Errorf("dfutil.GetAbsGlobExps() expectedGlobExps mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetSortedKeys(t *testing.T) {
|
|
tests := []struct {
|
|
testName string
|
|
input map[string]string
|
|
expected []string
|
|
}{
|
|
{
|
|
testName: "default",
|
|
input: map[string]string{"a": "av", "c": "cv", "b": "bv"},
|
|
expected: []string{"a", "b", "c"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.testName)
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
actual := dfutil.GetSortedKeys(tt.input)
|
|
if diff := cmp.Diff(tt.expected, actual); diff != "" {
|
|
t.Errorf("dfutil.GetSortedKeys() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetSplitValuesFromStr(t *testing.T) {
|
|
tests := []struct {
|
|
testName string
|
|
input string
|
|
expected []string
|
|
}{
|
|
{
|
|
testName: "Empty string",
|
|
input: "",
|
|
expected: []string{},
|
|
},
|
|
{
|
|
testName: "Single value",
|
|
input: "s1",
|
|
expected: []string{"s1"},
|
|
},
|
|
{
|
|
testName: "Multiple values",
|
|
input: "s1, s2, s3 ",
|
|
expected: []string{"s1", "s2", "s3"},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Log("Running test: ", tt.testName)
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
actual := dfutil.GetSplitValuesFromStr(tt.input)
|
|
if diff := cmp.Diff(tt.expected, actual); diff != "" {
|
|
t.Errorf("dfutil.GetSplitValuesFromStr() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetContainerPortsFromStrings(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
ports []string
|
|
containerPorts []corev1.ContainerPort
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "with normal port values and normal protocol values in lowercase",
|
|
ports: []string{"8080/tcp", "9090/udp"},
|
|
containerPorts: []corev1.ContainerPort{
|
|
{
|
|
Name: "8080-tcp",
|
|
ContainerPort: 8080,
|
|
Protocol: corev1.ProtocolTCP,
|
|
},
|
|
{
|
|
Name: "9090-udp",
|
|
ContainerPort: 9090,
|
|
Protocol: corev1.ProtocolUDP,
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "with normal port values and normal protocol values in mixed case",
|
|
ports: []string{"8080/TcP", "9090/uDp"},
|
|
containerPorts: []corev1.ContainerPort{
|
|
{
|
|
Name: "8080-tcp",
|
|
ContainerPort: 8080,
|
|
Protocol: corev1.ProtocolTCP,
|
|
},
|
|
{
|
|
Name: "9090-udp",
|
|
ContainerPort: 9090,
|
|
Protocol: corev1.ProtocolUDP,
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "with normal port values and with one protocol value not mentioned",
|
|
ports: []string{"8080", "9090/Udp"},
|
|
containerPorts: []corev1.ContainerPort{
|
|
{
|
|
Name: "8080-tcp",
|
|
ContainerPort: 8080,
|
|
Protocol: corev1.ProtocolTCP,
|
|
},
|
|
{
|
|
Name: "9090-udp",
|
|
ContainerPort: 9090,
|
|
Protocol: corev1.ProtocolUDP,
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "with normal port values and with one invalid protocol value",
|
|
ports: []string{"8080/blah", "9090/Udp"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "with invalid port values and normal protocol",
|
|
ports: []string{"ads/Tcp", "9090/Udp"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "with invalid port values and one missing protocol value",
|
|
ports: []string{"ads", "9090/Udp"},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ports, err := dfutil.GetContainerPortsFromStrings(tt.ports)
|
|
if err == nil && !tt.wantErr {
|
|
if diff := cmp.Diff(tt.containerPorts, ports); diff != "" {
|
|
t.Errorf("dfutil.GetContainerPortsFromStrings() containerPorts mismatch (-want +got):\n%s", diff)
|
|
}
|
|
} else if err == nil && tt.wantErr {
|
|
t.Error("error was expected, but no error was returned")
|
|
} else if err != nil && !tt.wantErr {
|
|
t.Errorf("test failed, no error was expected, but got unexpected error: %s", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsGlobExpMatch(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
testName string
|
|
strToMatch string
|
|
globExps []string
|
|
want bool
|
|
wantErr bool
|
|
}{
|
|
{
|
|
testName: "Test glob matches",
|
|
strToMatch: "/home/redhat/nodejs-ex/.git",
|
|
globExps: []string{"/home/redhat/nodejs-ex/.git", "/home/redhat/nodejs-ex/tests/"},
|
|
want: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
testName: "Test glob does not match",
|
|
strToMatch: "/home/redhat/nodejs-ex/gimmt.gimmt",
|
|
globExps: []string{"/home/redhat/nodejs-ex/.git/", "/home/redhat/nodejs-ex/tests/"},
|
|
want: false,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
testName: "Test glob match files",
|
|
strToMatch: "/home/redhat/nodejs-ex/openshift/templates/example.json",
|
|
globExps: []string{"/home/redhat/nodejs-ex/*.json", "/home/redhat/nodejs-ex/tests/"},
|
|
want: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
testName: "Test '**' glob matches",
|
|
strToMatch: "/home/redhat/nodejs-ex/openshift/templates/example.json",
|
|
globExps: []string{"/home/redhat/nodejs-ex/openshift/**/*.json"},
|
|
want: true,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
testName: "Test '!' in glob matches",
|
|
strToMatch: "/home/redhat/nodejs-ex/openshift/templates/example.json",
|
|
globExps: []string{"/home/redhat/nodejs-ex/!*.json", "/home/redhat/nodejs-ex/tests/"},
|
|
want: false,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
testName: "Test [ in glob matches",
|
|
strToMatch: "/home/redhat/nodejs-ex/openshift/templates/example.json",
|
|
globExps: []string{"/home/redhat/nodejs-ex/["},
|
|
want: false,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
testName: "Test '#' comment glob matches",
|
|
strToMatch: "/home/redhat/nodejs-ex/openshift/templates/example.json",
|
|
globExps: []string{"#/home/redhat/nodejs-ex/openshift/**/*.json"},
|
|
want: false,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.testName, func(t *testing.T) {
|
|
matched, err := dfutil.IsGlobExpMatch(tt.strToMatch, tt.globExps)
|
|
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("unexpected error %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
|
|
if tt.want != matched {
|
|
t.Errorf("expected %v, got %v", tt.want, matched)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRemoveRelativePathFromFiles(t *testing.T) {
|
|
type args struct {
|
|
path string
|
|
input []string
|
|
output []string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1 - Remove the relative path from a list of files",
|
|
args: args{
|
|
path: "/foo/bar",
|
|
input: []string{"/foo/bar/1", "/foo/bar/2", "/foo/bar/3/", "/foo/bar/4/5/foo/bar"},
|
|
output: []string{"1", "2", "3", "4/5/foo/bar"},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2 - Fail on purpose with an invalid path",
|
|
args: args{
|
|
path: `..`,
|
|
input: []string{"foo", "bar"},
|
|
output: []string{},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
// Run function RemoveRelativePathFromFiles
|
|
output, err := dfutil.RemoveRelativePathFromFiles(tt.args.input, tt.args.path)
|
|
if runtime.GOOS == "windows" {
|
|
for index, element := range output {
|
|
output[index] = filepath.ToSlash(element)
|
|
}
|
|
}
|
|
|
|
// Check for error
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("unexpected error %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
|
|
if diff := cmp.Diff(tt.args.output, output); diff != "" {
|
|
t.Errorf("dfutil.RemoveRelativePathFromFiles() output mismatch (-want +got):\n%s", diff)
|
|
}
|
|
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHTTPGetFreePort(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "case 1: get a valid free port",
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := dfutil.HTTPGetFreePort()
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("HTTPGetFreePort() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
addressLook := "localhost:" + strconv.Itoa(got)
|
|
listener, err := net.Listen("tcp", addressLook)
|
|
if err != nil {
|
|
t.Errorf("expected a free port, but listening failed cause: %v", err)
|
|
} else {
|
|
_ = listener.Close()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetRemoteFilesMarkedForDeletion(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
files []string
|
|
remotePath string
|
|
want []string
|
|
}{
|
|
{
|
|
name: "case 1: no files",
|
|
files: []string{},
|
|
remotePath: "/projects",
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "case 2: one file",
|
|
files: []string{"abc.txt"},
|
|
remotePath: "/projects",
|
|
want: []string{"/projects/abc.txt"},
|
|
},
|
|
{
|
|
name: "case 3: multiple files",
|
|
files: []string{"abc.txt", "def.txt", "hello.txt"},
|
|
remotePath: "/projects",
|
|
want: []string{"/projects/abc.txt", "/projects/def.txt", "/projects/hello.txt"},
|
|
},
|
|
{
|
|
name: "case 4: remote path multiple folders",
|
|
files: []string{"abc.txt", "def.txt", "hello.txt"},
|
|
remotePath: "/test/folder",
|
|
want: []string{"/test/folder/abc.txt", "/test/folder/def.txt", "/test/folder/hello.txt"},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
remoteFiles := dfutil.GetRemoteFilesMarkedForDeletion(tt.files, tt.remotePath)
|
|
if diff := cmp.Diff(tt.want, remoteFiles); diff != "" {
|
|
t.Errorf("dfutil.GetRemoteFilesMarkedForDeletion() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHTTPGetRequest(t *testing.T) {
|
|
// Start a local HTTP server
|
|
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
// Send response to be tested
|
|
_, err := rw.Write([]byte("OK"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}))
|
|
// Close the server when test finishes
|
|
defer server.Close()
|
|
|
|
tests := []struct {
|
|
name string
|
|
url string
|
|
want []byte
|
|
}{
|
|
{
|
|
name: "Case 1: Input url is valid",
|
|
url: server.URL,
|
|
// Want(Expected) result is "OK"
|
|
// According to Unicode table: O == 79, K == 75
|
|
want: []byte{79, 75},
|
|
},
|
|
{
|
|
name: "Case 2: Input url is invalid",
|
|
url: "invalid",
|
|
want: nil,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
request := dfutil.HTTPRequestParams{
|
|
URL: tt.url,
|
|
}
|
|
got, err := dfutil.HTTPGetRequest(request, 0)
|
|
|
|
if diff := cmp.Diff(tt.want, got); diff != "" {
|
|
t.Errorf("dfutil.HTTPGetRequest() mismatch (-want +got):\n%s", diff)
|
|
t.Logf("Error message is: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFilterIgnores(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
changedFiles []string
|
|
deletedFiles []string
|
|
ignoredFiles []string
|
|
wantChangedFiles []string
|
|
wantDeletedFiles []string
|
|
}{
|
|
{
|
|
name: "Case 1: No ignored files",
|
|
changedFiles: []string{"hello.txt", "test.abc"},
|
|
deletedFiles: []string{"one.txt", "two.txt"},
|
|
ignoredFiles: []string{},
|
|
wantChangedFiles: []string{"hello.txt", "test.abc"},
|
|
wantDeletedFiles: []string{"one.txt", "two.txt"},
|
|
},
|
|
{
|
|
name: "Case 2: One ignored file",
|
|
changedFiles: []string{"hello.txt", "test.abc"},
|
|
deletedFiles: []string{"one.txt", "two.txt"},
|
|
ignoredFiles: []string{"hello.txt"},
|
|
wantChangedFiles: []string{"test.abc"},
|
|
wantDeletedFiles: []string{"one.txt", "two.txt"},
|
|
},
|
|
{
|
|
name: "Case 3: Multiple ignored file",
|
|
changedFiles: []string{"hello.txt", "test.abc"},
|
|
deletedFiles: []string{"one.txt", "two.txt"},
|
|
ignoredFiles: []string{"hello.txt", "two.txt"},
|
|
wantChangedFiles: []string{"test.abc"},
|
|
wantDeletedFiles: []string{"one.txt"},
|
|
},
|
|
{
|
|
name: "Case 4: No changed or deleted files",
|
|
changedFiles: []string{""},
|
|
deletedFiles: []string{""},
|
|
ignoredFiles: []string{"hello.txt", "two.txt"},
|
|
wantChangedFiles: []string{""},
|
|
wantDeletedFiles: []string{""},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
filterChanged, filterDeleted := dfutil.FilterIgnores(tt.changedFiles, tt.deletedFiles, tt.ignoredFiles)
|
|
|
|
if diff := cmp.Diff(tt.wantChangedFiles, filterChanged); diff != "" {
|
|
t.Errorf("dfutil.FilterIgnores() wantChangedFiles mismatch (-want +got):\n%s", diff)
|
|
}
|
|
|
|
if diff := cmp.Diff(tt.wantDeletedFiles, filterDeleted); diff != "" {
|
|
t.Errorf("dfutil.FilterIgnores() wantDeletedFiles mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDownloadFile(t *testing.T) {
|
|
// Start a local HTTP server
|
|
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
// Send response to be tested
|
|
_, err := rw.Write([]byte("OK"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}))
|
|
// Close the server when test finishes
|
|
defer server.Close()
|
|
|
|
tests := []struct {
|
|
name string
|
|
url string
|
|
filepath string
|
|
want []byte
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Input url is valid",
|
|
url: server.URL,
|
|
filepath: "./test.yaml",
|
|
// Want(Expected) result is "OK"
|
|
// According to Unicode table: O == 79, K == 75
|
|
want: []byte{79, 75},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Input url is invalid",
|
|
url: "invalid",
|
|
filepath: "./test.yaml",
|
|
want: []byte{},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 3: Input url is an empty string",
|
|
url: "",
|
|
filepath: "./test.yaml",
|
|
want: []byte{},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gotErr := false
|
|
params := dfutil.DownloadParams{
|
|
Request: dfutil.HTTPRequestParams{
|
|
URL: tt.url,
|
|
},
|
|
Filepath: tt.filepath,
|
|
}
|
|
err := dfutil.DownloadFile(params)
|
|
if err != nil {
|
|
gotErr = true
|
|
}
|
|
if gotErr != tt.wantErr {
|
|
t.Errorf("Failed to get expected error: %v", err)
|
|
}
|
|
|
|
if !tt.wantErr {
|
|
if err != nil {
|
|
t.Errorf("Failed to download file with error %s", err)
|
|
}
|
|
|
|
got, err := os.ReadFile(tt.filepath)
|
|
if err != nil {
|
|
t.Errorf("Failed to read file with error %s", err)
|
|
}
|
|
|
|
if diff := cmp.Diff(tt.want, got); diff != "" {
|
|
t.Errorf("dfutil.DownloadFile() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
|
|
// Clean up the file that downloaded in this test case
|
|
err = os.Remove(tt.filepath)
|
|
if err != nil {
|
|
t.Errorf("Failed to delete file with error %s", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateK8sResourceName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key string
|
|
value string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "Case 1: Resource name is valid",
|
|
key: "component name",
|
|
value: "good-name",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "Case 2: Resource name contains unsupported character",
|
|
key: "component name",
|
|
value: "BAD@name",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "Case 3: Resource name contains all numeric values",
|
|
key: "component name",
|
|
value: "12345",
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := dfutil.ValidateK8sResourceName(tt.key, tt.value)
|
|
got := err == nil
|
|
if diff := cmp.Diff(tt.want, got); diff != "" {
|
|
t.Errorf("dfutil.ValidateK8sResourceName() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUnzip(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
src string
|
|
pathToUnzip string
|
|
expectedFiles []string
|
|
expectedError string
|
|
}{
|
|
{
|
|
name: "Case 1: Invalid source zip",
|
|
src: "../../tests/examples/source/devfiles/nodejs-zip/invalid.zip",
|
|
pathToUnzip: "",
|
|
expectedFiles: []string{},
|
|
expectedError: "open ../../tests/examples/source/devfiles/nodejs-zip/invalid.zip:",
|
|
},
|
|
{
|
|
name: "Case 2: Valid source zip, no pathToUnzip",
|
|
src: "../../tests/examples/source/devfiles/nodejs-zip/master.zip",
|
|
pathToUnzip: "",
|
|
expectedFiles: []string{"package.json", "package-lock.json", "app", "app/app.js", DotGitIgnoreFile, "LICENSE", "README.md"},
|
|
expectedError: "",
|
|
},
|
|
{
|
|
name: "Case 3: Valid source zip with pathToUnzip",
|
|
src: "../../tests/examples/source/devfiles/nodejs-zip/master.zip",
|
|
pathToUnzip: "app",
|
|
expectedFiles: []string{"app.js"},
|
|
expectedError: "",
|
|
},
|
|
{
|
|
name: "Case 4: Valid source zip with pathToUnzip - trailing /",
|
|
src: "../../tests/examples/source/devfiles/nodejs-zip/master.zip",
|
|
pathToUnzip: "app/",
|
|
expectedFiles: []string{"app.js"},
|
|
expectedError: "",
|
|
},
|
|
{
|
|
name: "Case 5: Valid source zip with pathToUnzip - leading /",
|
|
src: "../../tests/examples/source/devfiles/nodejs-zip/master.zip",
|
|
pathToUnzip: "app/",
|
|
expectedFiles: []string{"app.js"},
|
|
expectedError: "",
|
|
},
|
|
{
|
|
name: "Case 6: Valid source zip with pathToUnzip - leading and trailing /",
|
|
src: "../../tests/examples/source/devfiles/nodejs-zip/master.zip",
|
|
pathToUnzip: "/app/",
|
|
expectedFiles: []string{"app.js"},
|
|
expectedError: "",
|
|
},
|
|
{
|
|
name: "Case 7: Valid source zip with pathToUnzip - pattern",
|
|
src: "../../tests/examples/source/devfiles/nodejs-zip/master.zip",
|
|
pathToUnzip: "p*",
|
|
expectedFiles: []string{"package.json", "package-lock.json"},
|
|
expectedError: "",
|
|
},
|
|
{
|
|
name: "Case 8: Valid source zip with pathToUnzip - pattern and extension",
|
|
src: "../../tests/examples/source/devfiles/nodejs-zip/master.zip",
|
|
pathToUnzip: "*.json",
|
|
expectedFiles: []string{"package.json", "package-lock.json"},
|
|
expectedError: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
t.Logf(dir)
|
|
|
|
_, err := Unzip(filepath.FromSlash(tt.src), dir, tt.pathToUnzip, filesystem.DefaultFs{})
|
|
if err != nil {
|
|
tt.expectedError = strings.ReplaceAll(tt.expectedError, "/", string(filepath.Separator))
|
|
if !strings.HasPrefix(err.Error(), tt.expectedError) {
|
|
t.Errorf("Got err: '%s'\n expected err: '%s'", err.Error(), tt.expectedError)
|
|
}
|
|
} else {
|
|
for _, file := range tt.expectedFiles {
|
|
if _, err := os.Stat(filepath.Join(dir, file)); os.IsNotExist(err) {
|
|
t.Errorf("Expected file %s does not exist in directory after unzipping", file)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsValidProjectDir(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
devfilePath string
|
|
filesToCreate []string
|
|
dirToCreate []string
|
|
expectedError string
|
|
}{
|
|
{
|
|
name: "Case 1: Empty Folder",
|
|
devfilePath: "",
|
|
filesToCreate: []string{},
|
|
dirToCreate: []string{},
|
|
expectedError: "",
|
|
},
|
|
{
|
|
name: "Case 2: Folder contains devfile.yaml",
|
|
devfilePath: "devfile.yaml",
|
|
filesToCreate: []string{"devfile.yaml"},
|
|
dirToCreate: []string{},
|
|
expectedError: "",
|
|
},
|
|
{
|
|
name: "Case 3: Folder contains a file which is not the devfile",
|
|
devfilePath: "devfile.yaml",
|
|
filesToCreate: []string{"file1.yaml"},
|
|
dirToCreate: []string{},
|
|
expectedError: "folder %s doesn't contain the devfile used",
|
|
},
|
|
{
|
|
name: "Case 4: Folder contains a hidden file which is not the devfile",
|
|
devfilePath: "devfile.yaml",
|
|
filesToCreate: []string{".file1.yaml"},
|
|
dirToCreate: []string{},
|
|
expectedError: "folder %s doesn't contain the devfile used",
|
|
},
|
|
{
|
|
name: "Case 5: Folder contains devfile.yaml and more files",
|
|
devfilePath: "devfile.yaml",
|
|
filesToCreate: []string{"devfile.yaml", "file1.yaml", "file2.yaml"},
|
|
dirToCreate: []string{},
|
|
expectedError: "folder %s is not empty. It can only contain the devfile used",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
|
|
for _, f := range tt.filesToCreate {
|
|
file := filepath.Join(tmpDir, f)
|
|
if _, e := os.Create(file); e != nil {
|
|
t.Errorf("Error creating file %s. Err: %s", file, e)
|
|
}
|
|
}
|
|
|
|
for _, d := range tt.dirToCreate {
|
|
dir := filepath.Join(tmpDir, d)
|
|
if e := os.Mkdir(dir, os.FileMode(0644)); e != nil {
|
|
t.Errorf("Error creating dir %s. Err: %s", dir, e)
|
|
}
|
|
}
|
|
|
|
err := IsValidProjectDir(tmpDir, tt.devfilePath, filesystem.DefaultFs{})
|
|
expectedError := tt.expectedError
|
|
if expectedError != "" {
|
|
expectedError = fmt.Sprintf(expectedError, tmpDir)
|
|
}
|
|
|
|
if err != nil {
|
|
if diff := cmp.Diff(expectedError, err.Error()); diff != "" {
|
|
t.Errorf("IsValidProjectDir() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDownloadFileInMemory(t *testing.T) {
|
|
// Start a local HTTP server
|
|
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
// Send response to be tested
|
|
_, err := rw.Write([]byte("OK"))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}))
|
|
// Close the server when test finishes
|
|
defer server.Close()
|
|
|
|
tests := []struct {
|
|
name string
|
|
url string
|
|
want []byte
|
|
}{
|
|
{
|
|
name: "Case 1: Input url is valid",
|
|
url: server.URL,
|
|
want: []byte{79, 75},
|
|
},
|
|
{
|
|
name: "Case 2: Input url is invalid",
|
|
url: "invalid",
|
|
want: []byte(nil),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data, err := DownloadFileInMemory(dfutil.HTTPRequestParams{URL: tt.url})
|
|
if tt.url != "invalid" && err != nil {
|
|
t.Errorf("Failed to download file with error %s", err)
|
|
}
|
|
|
|
if diff := cmp.Diff(tt.want, data); diff != "" {
|
|
t.Errorf("DownloadFileInMemory() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
/*
|
|
func TestGetGitHubZipURL(t *testing.T) {
|
|
startPoint := "1.0.0"
|
|
branch := "my-branch"
|
|
tests := []struct {
|
|
name string
|
|
location string
|
|
branch string
|
|
startPoint string
|
|
expectedError string
|
|
}{
|
|
{
|
|
name: "Case 1: Invalid http request",
|
|
location: "http://github.com/che-samples/web-nodejs-sample/archive/master",
|
|
expectedError: "Invalid GitHub URL. Please use https://",
|
|
},
|
|
{
|
|
name: "Case 2: Invalid owner",
|
|
location: "https://github.com//web-nodejs-sample/archive/master",
|
|
expectedError: "Invalid GitHub URL: owner cannot be empty. Expecting 'https://github.com/<owner>/<repo>'",
|
|
},
|
|
{
|
|
name: "Case 3: Invalid repo",
|
|
location: "https://github.com/che-samples//archive/master",
|
|
expectedError: "Invalid GitHub URL: repo cannot be empty. Expecting 'https://github.com/<owner>/<repo>'",
|
|
},
|
|
{
|
|
name: "Case 4: Invalid HTTPS Github URL with tag and commit",
|
|
location: "https://github.com/che-samples/web-nodejs-sample.git",
|
|
branch: branch,
|
|
startPoint: startPoint,
|
|
expectedError: fmt.Sprintf("Branch %s and StartPoint %s specified as project reference, please only specify one", branch, startPoint),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
_, err := GetGitHubZipURL(tt.location, tt.branch, tt.startPoint)
|
|
if err != nil {
|
|
if !strings.Contains(err.Error(), tt.expectedError) {
|
|
t.Errorf("Got %s,\n want %s", err.Error(), tt.expectedError)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
*/
|
|
|
|
func TestValidateURL(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
url string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Valid URL",
|
|
url: "http://www.example.com/",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid URL, with port",
|
|
url: "http://192.168.1.10:30741/",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid URL, with port, login and password",
|
|
url: "http://user:pass@192.168.1.10:30741/",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Invalid URL - No host",
|
|
url: "http://",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 3: Invalid URL - No scheme",
|
|
url: "://www.example.com/",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 4: Invalid URL - Host contains reserved character",
|
|
url: "http://??##",
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 5: Invalid URL - Scheme contains reserved character",
|
|
url: "$$$,,://www.example.com",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gotErr := false
|
|
got := ValidateURL(tt.url)
|
|
if got != nil {
|
|
gotErr = true
|
|
}
|
|
|
|
if gotErr != tt.wantErr {
|
|
t.Errorf("Got %v, want %v", got, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateFile(t *testing.T) {
|
|
// Create temp dir and temp file
|
|
tempDir := t.TempDir()
|
|
tempFile, err := os.CreateTemp(tempDir, "")
|
|
if err != nil {
|
|
t.Errorf("Failed to create temp file: %s, error: %v", tempFile.Name(), err)
|
|
}
|
|
defer tempFile.Close()
|
|
|
|
tests := []struct {
|
|
name string
|
|
filePath string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Valid file path",
|
|
filePath: tempFile.Name(),
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Invalid file path",
|
|
filePath: "!@#",
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gotErr := false
|
|
err := dfutil.ValidateFile(tt.filePath)
|
|
if err != nil {
|
|
gotErr = true
|
|
}
|
|
if gotErr != tt.wantErr {
|
|
t.Errorf("Got error: %v, want error: %t", err, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCopyFile(t *testing.T) {
|
|
// Create temp dir
|
|
tempDir := t.TempDir()
|
|
|
|
// Create temp file under temp dir as source file
|
|
tempFile, err := os.CreateTemp(tempDir, "")
|
|
if err != nil {
|
|
t.Errorf("Failed to create temp file: %s, error: %v", tempFile.Name(), err)
|
|
}
|
|
defer tempFile.Close()
|
|
|
|
srcPath := tempFile.Name()
|
|
fakePath := "!@#/**"
|
|
dstPath := filepath.Join(tempDir, "dstFile")
|
|
info, _ := os.Stat(srcPath)
|
|
|
|
tests := []struct {
|
|
name string
|
|
srcPath string
|
|
dstPath string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Copy successfully",
|
|
srcPath: srcPath,
|
|
dstPath: dstPath,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Invalid source path",
|
|
srcPath: fakePath,
|
|
dstPath: dstPath,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 3: Invalid destination path",
|
|
srcPath: srcPath,
|
|
dstPath: fakePath,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gotErr := false
|
|
err = dfutil.CopyFile(tt.srcPath, tt.dstPath, info)
|
|
if err != nil {
|
|
gotErr = true
|
|
}
|
|
|
|
if gotErr != tt.wantErr {
|
|
t.Errorf("Got error: %v, want error: %t", err, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPathEqual(t *testing.T) {
|
|
currentDir, err := os.Getwd()
|
|
if err != nil {
|
|
t.Errorf("Can't get absolute path of current working directory with error: %v", err)
|
|
}
|
|
fileAbsPath := filepath.Join(currentDir, "file")
|
|
fileRelPath := filepath.Join(".", "file")
|
|
|
|
tests := []struct {
|
|
name string
|
|
firstPath string
|
|
secondPath string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "Case 1: Two paths (two absolute paths) are equal",
|
|
firstPath: fileAbsPath,
|
|
secondPath: fileAbsPath,
|
|
want: true,
|
|
},
|
|
{
|
|
name: "Case 2: Two paths (one absolute path, one relative path) are equal",
|
|
firstPath: fileAbsPath,
|
|
secondPath: fileRelPath,
|
|
want: true,
|
|
},
|
|
{
|
|
name: "Case 3: Two paths are not equal",
|
|
firstPath: fileAbsPath,
|
|
secondPath: filepath.Join(fileAbsPath, "file"),
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := dfutil.PathEqual(tt.firstPath, tt.secondPath)
|
|
if diff := cmp.Diff(tt.want, got); diff != "" {
|
|
t.Errorf("dfutil.PathEqual() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSliceContainsString(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
stringVal string
|
|
slice []string
|
|
wantVal bool
|
|
}{
|
|
{
|
|
name: "Case 1: string in valid slice",
|
|
stringVal: "string",
|
|
slice: []string{"string", "string2"},
|
|
wantVal: true,
|
|
},
|
|
{
|
|
name: "Case 2: string not in valid slice",
|
|
stringVal: "string3",
|
|
slice: []string{"string", "string2"},
|
|
wantVal: false,
|
|
},
|
|
{
|
|
name: "Case 3: string not in empty slice",
|
|
stringVal: "string",
|
|
slice: []string{},
|
|
wantVal: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gotVal := sliceContainsString(tt.stringVal, tt.slice)
|
|
|
|
if diff := cmp.Diff(tt.wantVal, gotVal); diff != "" {
|
|
t.Errorf("sliceContainsString() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// FileType custom type to indicate type of file
|
|
type FileType int
|
|
|
|
const (
|
|
// RegularFile enum to represent regular file
|
|
RegularFile FileType = 0
|
|
// Directory enum to represent directory
|
|
Directory FileType = 1
|
|
)
|
|
|
|
// FileProperties to contain meta-data of a file like, file/folder name, file/folder parent dir, file type and desired file modification type
|
|
type FileProperties struct {
|
|
FilePath string
|
|
FileType FileType
|
|
}
|
|
|
|
func folderCheck(originalFolderMode os.FileMode, newFolderInfo os.FileInfo, path string) error {
|
|
if originalFolderMode.String() != newFolderInfo.Mode().String() {
|
|
return fmt.Errorf("folder %s created with wrong permission", path)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func fileCheck(fs filesystem.Filesystem, originalFile filesystem.File, newFilePath string, newFileInfo os.FileInfo) error {
|
|
originalFileData, err := fs.ReadFile(originalFile.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
createdFileData, err := fs.ReadFile(newFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// check the written data
|
|
if string(createdFileData) == string(originalFileData) {
|
|
originalInfo, err := fs.Stat(originalFile.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// check the file permission
|
|
if newFileInfo.Mode() != originalInfo.Mode() {
|
|
return fmt.Errorf("file %s created with wrong permission", newFilePath)
|
|
}
|
|
} else {
|
|
return fmt.Errorf("file %s created with wrong data", newFilePath)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func setupFileTest(fs filesystem.Filesystem, sourceName string, filePaths []FileProperties) (map[string]filesystem.File, map[string]os.FileMode, error) {
|
|
|
|
fileMap := make(map[string]filesystem.File)
|
|
folderMap := make(map[string]os.FileMode)
|
|
|
|
for i, path := range filePaths {
|
|
|
|
if path.FileType == RegularFile {
|
|
file, err := fs.Create(path.FilePath)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
_, err = file.Write([]byte("some text" + string(rune(i))))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
name, err := filepath.Rel(sourceName, file.Name())
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
fileMap[name] = file
|
|
} else if path.FileType == Directory {
|
|
permission := os.ModeDir + 0755
|
|
err := fs.MkdirAll(path.FilePath, permission)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
name, err := filepath.Rel(sourceName, path.FilePath)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
folderMap[name] = permission
|
|
}
|
|
}
|
|
|
|
return fileMap, folderMap, nil
|
|
}
|
|
|
|
func TestCopyFileWithFS(t *testing.T) {
|
|
fileName := "blah.js"
|
|
|
|
fs := filesystem.NewFakeFs()
|
|
|
|
sourceName := filepath.Join(os.TempDir(), "source")
|
|
destinationDirName := filepath.Join(os.TempDir(), "destination")
|
|
|
|
filePaths := []FileProperties{
|
|
{
|
|
FilePath: sourceName,
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, fileName),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: destinationDirName,
|
|
FileType: Directory,
|
|
},
|
|
}
|
|
|
|
printError := func(err error) {
|
|
t.Errorf("some error occured while procession file/folder: %v", err)
|
|
}
|
|
|
|
type args struct {
|
|
src string
|
|
dst string
|
|
fs filesystem.Filesystem
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "case 1: normal file exists",
|
|
args: args{
|
|
src: filepath.Join(sourceName, fileName),
|
|
dst: filepath.Join(destinationDirName, fileName),
|
|
fs: fs,
|
|
},
|
|
},
|
|
{
|
|
name: "case 2: file doesn't exist",
|
|
args: args{
|
|
src: filepath.Join(sourceName, fileName) + "blah",
|
|
dst: filepath.Join(destinationDirName, fileName),
|
|
fs: fs,
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fileMap, _, err := setupFileTest(fs, sourceName, filePaths)
|
|
if err != nil {
|
|
t.Errorf("error while setting up test: %v", err)
|
|
}
|
|
|
|
err = copyFileWithFs(tt.args.src, tt.args.dst, tt.args.fs)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("MoveFile() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
|
|
if tt.wantErr {
|
|
return
|
|
}
|
|
|
|
files, err := fs.ReadDir(destinationDirName)
|
|
if err != nil {
|
|
t.Errorf("error occured while reading directory %s: %v", destinationDirName, err)
|
|
}
|
|
|
|
found := false
|
|
for _, file := range files {
|
|
|
|
relPath, err := filepath.Rel(destinationDirName, filepath.Join(destinationDirName, fileName))
|
|
if err != nil {
|
|
printError(err)
|
|
break
|
|
}
|
|
|
|
if originalFile, ok := fileMap[relPath]; ok {
|
|
err := fileCheck(fs, originalFile, filepath.Join(destinationDirName, file.Name()), file)
|
|
if err != nil {
|
|
break
|
|
}
|
|
found = true
|
|
} else {
|
|
t.Errorf("extra file %s created", file.Name())
|
|
}
|
|
}
|
|
|
|
if !found && !tt.wantErr {
|
|
t.Errorf("%s not created in directory %s", fileName, destinationDirName)
|
|
}
|
|
|
|
_ = fs.RemoveAll(tt.args.src)
|
|
_ = fs.RemoveAll(tt.args.dst)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCopyDirWithFS(t *testing.T) {
|
|
|
|
fs := filesystem.NewFakeFs()
|
|
|
|
sourceName := filepath.Join(os.TempDir(), "source")
|
|
destinationName := filepath.Join(os.TempDir(), "destination")
|
|
|
|
filePaths := []FileProperties{
|
|
{
|
|
FilePath: sourceName,
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main"),
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "blah.js"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "some-other-blah.js"),
|
|
FileType: RegularFile,
|
|
},
|
|
}
|
|
|
|
printError := func(err error) {
|
|
t.Errorf("some error occured while procession file/folder: %v", err)
|
|
}
|
|
|
|
type args struct {
|
|
src string
|
|
dst string
|
|
fs filesystem.Filesystem
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "case 1: folder with a nested file and folder",
|
|
args: args{
|
|
src: sourceName,
|
|
dst: destinationName,
|
|
fs: fs,
|
|
},
|
|
},
|
|
{
|
|
name: "case 2: source folder doesn't exist",
|
|
args: args{
|
|
src: sourceName + "/extra",
|
|
dst: destinationName,
|
|
fs: fs,
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fileMap, folderMap, err := setupFileTest(fs, sourceName, filePaths)
|
|
if err != nil {
|
|
t.Errorf("error while setting up test: %v", err)
|
|
}
|
|
|
|
err = CopyDirWithFS(tt.args.src, tt.args.dst, tt.args.fs)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("MoveDir() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
|
|
if tt.wantErr && err != nil {
|
|
return
|
|
}
|
|
|
|
folderCount := 0
|
|
fileCount := 0
|
|
|
|
err = fs.Walk(destinationName, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
relPath, err := filepath.Rel(destinationName, path)
|
|
if err != nil {
|
|
printError(err)
|
|
return err
|
|
}
|
|
|
|
if info.IsDir() {
|
|
|
|
// check the permission on the folder
|
|
if originalFolderMode, ok := folderMap[relPath]; ok {
|
|
err := folderCheck(originalFolderMode, info, path)
|
|
if err != nil {
|
|
printError(err)
|
|
return err
|
|
}
|
|
folderCount++
|
|
} else {
|
|
t.Errorf("extra folder %s created", path)
|
|
}
|
|
} else {
|
|
if file, ok := fileMap[relPath]; ok {
|
|
err := fileCheck(fs, file, path, info)
|
|
if err != nil {
|
|
printError(err)
|
|
return err
|
|
}
|
|
fileCount++
|
|
} else {
|
|
t.Errorf("extra file %s created", path)
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
|
|
if folderCount != 2 {
|
|
t.Errorf("some folder were not created")
|
|
}
|
|
|
|
if fileCount != 2 {
|
|
t.Errorf("some files were not created")
|
|
}
|
|
|
|
_ = fs.RemoveAll(tt.args.src)
|
|
_ = fs.RemoveAll(tt.args.dst)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCleanDir(t *testing.T) {
|
|
fs := filesystem.NewFakeFs()
|
|
|
|
sourceName := filepath.Join(os.TempDir(), "source")
|
|
|
|
filePaths := []FileProperties{
|
|
{
|
|
FilePath: sourceName,
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main"),
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "src"),
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "devfile.yaml"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "preference.yaml"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "blah.js"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "some-other-blah.js"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "src", "another-blah.js"),
|
|
FileType: RegularFile,
|
|
},
|
|
}
|
|
|
|
type args struct {
|
|
originalPath string
|
|
leaveBehindFiles map[string]bool
|
|
fs filesystem.Filesystem
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "case 1: leave behind two files",
|
|
args: args{
|
|
originalPath: sourceName,
|
|
fs: fs,
|
|
leaveBehindFiles: map[string]bool{
|
|
"devfile.yaml": true,
|
|
"preference.yaml": true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "case 2: source doesn't exist",
|
|
args: args{
|
|
originalPath: sourceName + "blah",
|
|
fs: fs,
|
|
leaveBehindFiles: map[string]bool{
|
|
"devfile.yaml": true,
|
|
"preference.yaml": true,
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
_, _, err := setupFileTest(fs, sourceName, filePaths)
|
|
if err != nil {
|
|
t.Errorf("error while setting up test: %v", err)
|
|
}
|
|
|
|
err = cleanDir(tt.args.originalPath, tt.args.leaveBehindFiles, tt.args.fs)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("CleanDir() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
|
|
if err != nil && tt.wantErr {
|
|
return
|
|
}
|
|
|
|
files, err := fs.ReadDir(sourceName)
|
|
if err != nil {
|
|
t.Errorf("error occured while reading directory %s: %v", sourceName, err)
|
|
}
|
|
|
|
found := 0
|
|
for _, file := range files {
|
|
if _, ok := tt.args.leaveBehindFiles[file.Name()]; !ok {
|
|
t.Errorf("file %s isn't cleaned up", file.Name())
|
|
} else {
|
|
found++
|
|
}
|
|
}
|
|
|
|
if found != 2 {
|
|
t.Errorf("some extra file were deleted")
|
|
}
|
|
|
|
_ = fs.RemoveAll(tt.args.originalPath)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGitSubDir(t *testing.T) {
|
|
|
|
fs := filesystem.NewFakeFs()
|
|
|
|
sourceName := filepath.Join(os.TempDir(), "source")
|
|
destinationName := filepath.Join(os.TempDir(), "destination")
|
|
|
|
filePaths := []FileProperties{
|
|
{
|
|
FilePath: sourceName,
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main"),
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "blah.js"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "some-other-blah.js"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "test"),
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "test", "test.java"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "src", "java"),
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "src", "java", "main.java"),
|
|
FileType: RegularFile,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "src", "resources"),
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "src", "resources", "layout"),
|
|
FileType: Directory,
|
|
},
|
|
{
|
|
FilePath: filepath.Join(sourceName, "main", "src", "resources", "index.html"),
|
|
FileType: RegularFile,
|
|
},
|
|
}
|
|
|
|
type args struct {
|
|
destinationPath string
|
|
srcPath string
|
|
subDir string
|
|
fs filesystem.Filesystem
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "case 1: normal sub dir exist",
|
|
args: args{
|
|
srcPath: sourceName,
|
|
destinationPath: destinationName,
|
|
subDir: filepath.Join("main", "src"),
|
|
fs: fs,
|
|
},
|
|
},
|
|
{
|
|
name: "case 2: sub dir doesn't exist",
|
|
args: args{
|
|
srcPath: sourceName,
|
|
destinationPath: destinationName,
|
|
subDir: filepath.Join("main", "blah"),
|
|
fs: fs,
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "case 3: src doesn't exist",
|
|
args: args{
|
|
srcPath: sourceName + "blah",
|
|
destinationPath: destinationName,
|
|
subDir: filepath.Join("main", "src"),
|
|
fs: fs,
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
_, _, err := setupFileTest(fs, sourceName, filePaths)
|
|
if err != nil {
|
|
t.Errorf("error while setting up test: %v", err)
|
|
}
|
|
|
|
err = gitSubDir(tt.args.srcPath, tt.args.destinationPath, tt.args.subDir, tt.args.fs)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("GitSubDir() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
|
|
if tt.wantErr && err != nil {
|
|
return
|
|
}
|
|
|
|
pathsToValidate := map[string]bool{
|
|
filepath.Join(tt.args.destinationPath, "java"): true,
|
|
filepath.Join(tt.args.destinationPath, "java", "main.java"): true,
|
|
filepath.Join(tt.args.destinationPath, "resources"): true,
|
|
filepath.Join(tt.args.destinationPath, "resources", "layout"): true,
|
|
filepath.Join(tt.args.destinationPath, "resources", "index.html"): true,
|
|
}
|
|
|
|
pathsNotToBePresent := map[string]bool{
|
|
filepath.Join(tt.args.destinationPath, "src"): true,
|
|
filepath.Join(tt.args.destinationPath, "main"): true,
|
|
}
|
|
|
|
found := 0
|
|
notToBeFound := 0
|
|
err = fs.Walk(tt.args.destinationPath, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if ok := pathsToValidate[path]; ok {
|
|
found++
|
|
}
|
|
|
|
if ok := pathsNotToBePresent[path]; ok {
|
|
notToBeFound++
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Errorf("unexpected error: %v", err)
|
|
}
|
|
|
|
if found != 5 {
|
|
t.Errorf("all files were not copied")
|
|
}
|
|
|
|
if notToBeFound != 0 {
|
|
t.Errorf("extra files were created")
|
|
}
|
|
|
|
_, err = os.Stat(tt.args.srcPath)
|
|
if !os.IsNotExist(err) {
|
|
t.Errorf("src path was not deleted")
|
|
}
|
|
|
|
_ = fs.RemoveAll(tt.args.srcPath)
|
|
_ = fs.RemoveAll(tt.args.destinationPath)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetCommandStringFromEnvs(t *testing.T) {
|
|
type args struct {
|
|
envVars []v1alpha2.EnvVar
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want string
|
|
}{
|
|
{
|
|
name: "case 1: three envs given",
|
|
args: args{
|
|
envVars: []v1alpha2.EnvVar{
|
|
{
|
|
Name: "foo",
|
|
Value: "bar",
|
|
},
|
|
{
|
|
Name: "JAVA_HOME",
|
|
Value: "/home/user/java",
|
|
},
|
|
{
|
|
Name: "GOPATH",
|
|
Value: "/home/user/go",
|
|
},
|
|
},
|
|
},
|
|
want: "export foo=\"bar\" JAVA_HOME=\"/home/user/java\" GOPATH=\"/home/user/go\"",
|
|
},
|
|
{
|
|
name: "case 2: no envs given",
|
|
args: args{
|
|
envVars: []v1alpha2.EnvVar{},
|
|
},
|
|
want: "",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := GetCommandStringFromEnvs(tt.args.envVars); got != tt.want {
|
|
t.Errorf("GetCommandStringFromEnvs() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetGitOriginPath(t *testing.T) {
|
|
tempGitDirWithOrigin := t.TempDir()
|
|
|
|
repoWithOrigin, err := git.PlainInit(tempGitDirWithOrigin, true)
|
|
if err != nil {
|
|
t.Errorf("unexpected error %v", err)
|
|
}
|
|
|
|
_, err = repoWithOrigin.CreateRemote(&config.RemoteConfig{
|
|
Name: "origin",
|
|
URLs: []string{"git@github.com:redhat-developer/odo.git"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("unexpected error %v", err)
|
|
}
|
|
|
|
tempGitDirWithoutOrigin := t.TempDir()
|
|
|
|
repoWithoutOrigin, err := git.PlainInit(tempGitDirWithoutOrigin, true)
|
|
if err != nil {
|
|
t.Errorf("unexpected error %v", err)
|
|
}
|
|
|
|
_, err = repoWithoutOrigin.CreateRemote(&config.RemoteConfig{
|
|
Name: "upstream",
|
|
URLs: []string{"git@github.com:redhat-developer/odo.git"},
|
|
})
|
|
if err != nil {
|
|
t.Errorf("unexpected error %v", err)
|
|
}
|
|
|
|
type args struct {
|
|
path string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want string
|
|
}{
|
|
{
|
|
name: "case 1: remote named origin exists",
|
|
args: args{
|
|
path: tempGitDirWithOrigin,
|
|
},
|
|
want: "git@github.com:redhat-developer/odo.git",
|
|
},
|
|
{
|
|
name: "case 2: remote named origin doesn't exists",
|
|
args: args{
|
|
path: tempGitDirWithoutOrigin,
|
|
},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "case 3: not a git repo",
|
|
args: args{
|
|
path: "",
|
|
},
|
|
want: "",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := GetGitOriginPath(tt.args.path); got != tt.want {
|
|
t.Errorf("GetGitOriginPath() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConvertLabelsToSelector(t *testing.T) {
|
|
cases := []struct {
|
|
labels map[string]string
|
|
want string
|
|
}{
|
|
{
|
|
labels: map[string]string{
|
|
"app": "app",
|
|
"app.kubernetes.io/managed-by": "odo",
|
|
"app.kubernetes.io/managed-by-version": "v2.1",
|
|
},
|
|
want: "app=app,app.kubernetes.io/managed-by=odo,app.kubernetes.io/managed-by-version=v2.1",
|
|
},
|
|
{
|
|
labels: map[string]string{
|
|
"app": "app",
|
|
"app.kubernetes.io/managed-by": "!odo",
|
|
"app.kubernetes.io/managed-by-version": "4.8",
|
|
},
|
|
want: "app=app,app.kubernetes.io/managed-by!=odo,app.kubernetes.io/managed-by-version=4.8",
|
|
},
|
|
{
|
|
labels: map[string]string{
|
|
"app.kubernetes.io/managed-by": "odo",
|
|
},
|
|
want: "app.kubernetes.io/managed-by=odo",
|
|
},
|
|
{
|
|
labels: map[string]string{
|
|
"app.kubernetes.io/managed-by": "!odo",
|
|
},
|
|
want: "app.kubernetes.io/managed-by!=odo",
|
|
},
|
|
}
|
|
|
|
for _, tt := range cases {
|
|
got := ConvertLabelsToSelector(tt.labels)
|
|
if got != tt.want {
|
|
t.Errorf("got: %q\nwant:%q", got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNamespaceKubernetesObjectWithTrim(t *testing.T) {
|
|
type args struct {
|
|
componentName string
|
|
applicationName string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "case 1: hyphenated name is less than 63 characters",
|
|
args: args{
|
|
componentName: "nodejs",
|
|
applicationName: "app",
|
|
},
|
|
want: "nodejs-app",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "case 2: hyphenated name is more than 63 characters",
|
|
args: args{
|
|
componentName: "veryveryveryveryveryLongComponentName",
|
|
applicationName: "veryveryveryveryveryveryLongAppName",
|
|
},
|
|
want: "veryveryveryveryveryLongCompone-veryveryveryveryveryveryLongApp",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "case 3: hyphenated name is equal to 63 characters",
|
|
args: args{
|
|
componentName: "veryveryveryveryLongComponentGo",
|
|
applicationName: "veryveryveryveryLongAppNameInGo",
|
|
},
|
|
want: "veryveryveryveryLongComponentGo-veryveryveryveryLongAppNameInGo",
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "case 4: component name is more than 63 characters",
|
|
args: args{
|
|
componentName: "123456789012345678901234567890123456789012345678901234567890ComponentName",
|
|
applicationName: "app",
|
|
},
|
|
want: "12345678901234567890123456789012345678901234567890123456789-app",
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := NamespaceKubernetesObjectWithTrim(tt.args.componentName, tt.args.applicationName, 63)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("NamespaceKubernetesObjectWithTrim() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("NamespaceKubernetesObjectWithTrim() got = %v, want %v", got, tt.want)
|
|
}
|
|
|
|
if len(got) > 63 {
|
|
t.Errorf("got = %s should be less than or equal to 63 characters", got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSafeGetBool(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
name string
|
|
arg *bool
|
|
want bool
|
|
}{
|
|
{
|
|
name: "case 1: nil pointer",
|
|
arg: nil,
|
|
want: false,
|
|
},
|
|
{
|
|
name: "case 2: true",
|
|
arg: GetBool(true),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "case 3: false",
|
|
arg: GetBool(false),
|
|
want: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := SafeGetBool(tt.arg); got != tt.want {
|
|
t.Errorf("SafeGetBool() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDisplayLog(t *testing.T) {
|
|
const compName = "my-comp"
|
|
type args struct {
|
|
input []string
|
|
numLines int
|
|
}
|
|
for _, tt := range []struct {
|
|
name string
|
|
wantErr bool
|
|
want []string
|
|
|
|
args
|
|
}{
|
|
{
|
|
name: "numberOfLastLines==-1",
|
|
args: args{
|
|
input: []string{"a", "b", "c"},
|
|
numLines: -1,
|
|
},
|
|
want: []string{"a\n", "b\n", "c\n"},
|
|
},
|
|
{
|
|
name: "numberOfLastLines greater than total number of lines read",
|
|
args: args{
|
|
input: []string{"one-line"},
|
|
numLines: 10,
|
|
},
|
|
want: []string{"one-line\n"},
|
|
},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
var b bytes.Buffer
|
|
for _, s := range tt.input {
|
|
if _, err := b.WriteString(s + "\n"); err != nil {
|
|
t.Errorf(" failed to write input data %q", s)
|
|
return
|
|
}
|
|
}
|
|
var w bytes.Buffer
|
|
err := DisplayLog(false, io.NopCloser(&b), &w, compName, tt.numLines)
|
|
|
|
if tt.wantErr != (err != nil) {
|
|
t.Errorf("expected %v, got %v", tt.wantErr, err)
|
|
return
|
|
}
|
|
|
|
//Read w
|
|
reader := bufio.NewReader(&w)
|
|
var lines []string
|
|
var line string
|
|
for {
|
|
line, err = reader.ReadString('\n')
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
t.Errorf("unexpected err while reading data: %v", err)
|
|
return
|
|
}
|
|
lines = append(lines, line)
|
|
}
|
|
if diff := cmp.Diff(tt.want, lines); diff != "" {
|
|
t.Errorf("DisplayLog() mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_addFileToIgnoreFile(t *testing.T) {
|
|
type args struct {
|
|
data string
|
|
ignore string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
want string
|
|
}{
|
|
{
|
|
name: ".odo already present as .odo",
|
|
args: args{
|
|
data: ".odo",
|
|
ignore: ".odo",
|
|
},
|
|
want: ".odo",
|
|
},
|
|
{
|
|
name: ".odo not present",
|
|
args: args{
|
|
data: `foo
|
|
bar`,
|
|
ignore: ".odo",
|
|
},
|
|
want: `foo
|
|
bar
|
|
.odo`,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
fs := filesystem.NewFakeFs()
|
|
var data = []byte(tt.args.data)
|
|
path := "/.gitignore"
|
|
err := fs.WriteFile(path, data, 0644)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
if err = addFileToIgnoreFile(path, tt.args.ignore, fs); (err != nil) != tt.wantErr {
|
|
t.Errorf("addFileToIgnoreFile() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
var content []byte
|
|
content, err = fs.ReadFile(path)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if string(content) != tt.want {
|
|
t.Errorf("expected \n%s\ngot \n%s", tt.want, string(content))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsPortFree(t *testing.T) {
|
|
type serverCloser interface {
|
|
Close()
|
|
}
|
|
type args struct {
|
|
port int
|
|
portProvider func(address string) (int, serverCloser, error)
|
|
address string
|
|
}
|
|
type test struct {
|
|
name string
|
|
args args
|
|
want bool
|
|
}
|
|
tests := []test{
|
|
{
|
|
name: "negative port should return an error, handles as false",
|
|
args: args{port: -10},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "0 should always be free",
|
|
args: args{port: 0},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "random port bound on 127.0.0.1",
|
|
args: args{
|
|
portProvider: func(address string) (int, serverCloser, error) {
|
|
s := httptest.NewServer(nil)
|
|
_, p, err := net.SplitHostPort(strings.TrimPrefix(s.URL, "http://"))
|
|
if err != nil {
|
|
return 0, s, err
|
|
}
|
|
port, err := strconv.Atoi(p)
|
|
if err != nil {
|
|
return 0, s, err
|
|
}
|
|
return port, s, nil
|
|
},
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "random port bound on 127.0.0.1 and checking 0 as input",
|
|
args: args{
|
|
portProvider: func(address string) (int, serverCloser, error) {
|
|
s := httptest.NewServer(nil)
|
|
return 0, s, nil
|
|
},
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "random port bound on 0.0.0.0 and checking 0 as input",
|
|
args: args{
|
|
portProvider: func(address string) (int, serverCloser, error) {
|
|
// Intentionally not using httptest.Server, which listens to 127.0.0.1
|
|
l, err := net.Listen("tcp", fmt.Sprintf("%s:0", address))
|
|
if err != nil {
|
|
return 0, nil, err
|
|
}
|
|
s := &httptest.Server{
|
|
Listener: l,
|
|
Config: &http.Server{},
|
|
}
|
|
s.Start()
|
|
|
|
return 0, s, nil
|
|
},
|
|
address: "0.0.0.0",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "random port bound on 0.0.0.0",
|
|
args: args{
|
|
portProvider: func(address string) (int, serverCloser, error) {
|
|
// Intentionally not using httptest.Server, which listens to 127.0.0.1
|
|
l, err := net.Listen("tcp", fmt.Sprintf("%s:0", address))
|
|
if err != nil {
|
|
return 0, nil, err
|
|
}
|
|
s := &httptest.Server{
|
|
Listener: l,
|
|
Config: &http.Server{},
|
|
}
|
|
s.Start()
|
|
|
|
_, p, err := net.SplitHostPort(strings.TrimPrefix(s.URL, "http://"))
|
|
if err != nil {
|
|
return 0, s, err
|
|
}
|
|
port, err := strconv.Atoi(p)
|
|
if err != nil {
|
|
return 0, s, err
|
|
}
|
|
return port, s, nil
|
|
},
|
|
address: "0.0.0.0",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
port := tt.args.port
|
|
var s serverCloser
|
|
var err error
|
|
if tt.args.portProvider != nil {
|
|
port, s, err = tt.args.portProvider(tt.args.address)
|
|
if s != nil {
|
|
defer s.Close()
|
|
}
|
|
if err != nil {
|
|
t.Errorf("error while computing port: %v", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
if got := IsPortFree(port, tt.args.address); got != tt.want {
|
|
t.Errorf("IsPortFree() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|