Skip to content

Commit

Permalink
Add unit and integration tests
Browse files Browse the repository at this point in the history
Signed-off-by: Parthvi Vala <[email protected]>
  • Loading branch information
valaparthvi committed Apr 25, 2023
1 parent b92e852 commit 5fa1b15
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 235 deletions.
6 changes: 3 additions & 3 deletions pkg/dev/podmandev/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ func getPortMapping(devfileObj parser.DevfileObj, debug bool, randomPorts bool,
freePort = getCustomLocalPort(ep.TargetPort, containerName)
if freePort == 0 {
for {
freePort, err = util.NextFreePort(startPort, endPort, usedPorts)
freePort, err = util.NextFreePort(startPort, endPort, usedPorts, address)
if err != nil {
klog.Infof("%s", err)
continue
Expand All @@ -294,15 +294,15 @@ func getPortMapping(devfileObj parser.DevfileObj, debug bool, randomPorts bool,
rand.Seed(time.Now().UnixNano()) // #nosec
for {
freePort = rand.Intn(endPort-startPort+1) + startPort // #nosec
if !isPortUsedInContainer(freePort) && util.IsPortFree(freePort) {
if !isPortUsedInContainer(freePort) && util.IsPortFree(freePort, address) {
break
}
time.Sleep(100 * time.Millisecond)
}
}
} else {
for {
freePort, err = util.NextFreePort(startPort, endPort, usedPorts)
freePort, err = util.NextFreePort(startPort, endPort, usedPorts, address)
if err != nil {
klog.Infof("%s", err)
continue epLoop
Expand Down
12 changes: 6 additions & 6 deletions pkg/portForward/kubeportforward/portForward.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ func (o *PFClient) StartPortForwarding(ctx context.Context, devFileObj parser.De

var portPairs map[string][]string
if len(definedPorts) != 0 {
portPairs = getCustomPortPairs(definedPorts, ceMapping)
portPairs = getCustomPortPairs(definedPorts, ceMapping, customAddress)
} else if randomPorts {
portPairs = randomPortPairsFromContainerEndpoints(ceMapping)
} else {
portPairs = portPairsFromContainerEndpoints(ceMapping)
portPairs = portPairsFromContainerEndpoints(ceMapping, customAddress)
}
var portPairsSlice []string
for _, v1 := range portPairs {
Expand Down Expand Up @@ -171,7 +171,7 @@ func (o *PFClient) GetForwardedPorts() map[string][]v1alpha2.Endpoint {

// getCustomPortPairs assigns custom port on localhost to a container port if provided by the definedPorts config,
// if not, it assigns a port starting from 20001 as done in portPairsFromContainerEndpoints
func getCustomPortPairs(definedPorts []api.ForwardedPort, ceMapping map[string][]v1alpha2.Endpoint) map[string][]string {
func getCustomPortPairs(definedPorts []api.ForwardedPort, ceMapping map[string][]v1alpha2.Endpoint, address string) map[string][]string {
portPairs := make(map[string][]string)
usedPorts := make(map[int]struct{})
for _, dPort := range definedPorts {
Expand Down Expand Up @@ -210,7 +210,7 @@ func getCustomPortPairs(definedPorts []api.ForwardedPort, ceMapping map[string][
if freePort == 0 {
for {
var err error
freePort, err = util.NextFreePort(startPort, endPort, nil)
freePort, err = util.NextFreePort(startPort, endPort, nil, address)
if err != nil {
klog.Infof("%s", err)
continue
Expand Down Expand Up @@ -250,13 +250,13 @@ func randomPortPairsFromContainerEndpoints(ceMap map[string][]v1alpha2.Endpoint)
// portPairsFromContainerEndpoints assigns a port on localhost to each port in the provided containerEndpoints map
// it returns a map of the format "<container-name>":{"<local-port-1>:<remote-port-1>", "<local-port-2>:<remote-port-2>"}
// "container1": {"20001:3000", "20002:3001"}
func portPairsFromContainerEndpoints(ceMap map[string][]v1alpha2.Endpoint) map[string][]string {
func portPairsFromContainerEndpoints(ceMap map[string][]v1alpha2.Endpoint, address string) map[string][]string {
portPairs := make(map[string][]string)
startPort := 20001
endPort := startPort + 10000
for name, ports := range ceMap {
for _, p := range ports {
freePort, err := util.NextFreePort(startPort, endPort, nil)
freePort, err := util.NextFreePort(startPort, endPort, nil, address)
if err != nil {
klog.Infof("%s", err)
continue
Expand Down
13 changes: 8 additions & 5 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -781,9 +781,12 @@ func SafeGetBool(b *bool) bool {
return *b
}

// IsPortFree checks if the port on localhost is free to use
func IsPortFree(port int) bool {
address := fmt.Sprintf("0.0.0.0:%d", port)
// IsPortFree checks if the port on a given address is free to use
func IsPortFree(port int, localAddress string) bool {
if localAddress == "" {
localAddress = "localhost"
}
address := fmt.Sprintf("%s:%d", localAddress, port)
listener, err := net.Listen("tcp", address)
if err != nil {
return false
Expand All @@ -795,15 +798,15 @@ func IsPortFree(port int) bool {
// NextFreePort returns the next free port on system, starting at start
// end finishing at end.
// If no port is found in the range [start, end], 0 is returned
func NextFreePort(start, end int, usedPorts []int) (int, error) {
func NextFreePort(start, end int, usedPorts []int, address string) (int, error) {
port := start
for {
for _, usedPort := range usedPorts {
if usedPort == port {
return port, nil
}
}
if IsPortFree(port) {
if IsPortFree(port, address) {
return port, nil
}
port++
Expand Down
21 changes: 12 additions & 9 deletions pkg/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2742,7 +2742,8 @@ func TestIsPortFree(t *testing.T) {
}
type args struct {
port int
portProvider func() (int, serverCloser, error)
portProvider func(address string) (int, serverCloser, error)
address string
}
type test struct {
name string
Expand All @@ -2763,7 +2764,7 @@ func TestIsPortFree(t *testing.T) {
{
name: "random port bound on 127.0.0.1",
args: args{
portProvider: func() (int, serverCloser, error) {
portProvider: func(address string) (int, serverCloser, error) {
s := httptest.NewServer(nil)
_, p, err := net.SplitHostPort(strings.TrimPrefix(s.URL, "http://"))
if err != nil {
Expand All @@ -2781,7 +2782,7 @@ func TestIsPortFree(t *testing.T) {
{
name: "random port bound on 127.0.0.1 and checking 0 as input",
args: args{
portProvider: func() (int, serverCloser, error) {
portProvider: func(address string) (int, serverCloser, error) {
s := httptest.NewServer(nil)
return 0, s, nil
},
Expand All @@ -2791,9 +2792,9 @@ func TestIsPortFree(t *testing.T) {
{
name: "random port bound on 0.0.0.0 and checking 0 as input",
args: args{
portProvider: func() (int, serverCloser, error) {
portProvider: func(address string) (int, serverCloser, error) {
// Intentionally not using httptest.Server, which listens to 127.0.0.1
l, err := net.Listen("tcp", "0.0.0.0:0")
l, err := net.Listen("tcp", fmt.Sprintf("%s:0", address))
if err != nil {
return 0, nil, err
}
Expand All @@ -2805,15 +2806,16 @@ func TestIsPortFree(t *testing.T) {

return 0, s, nil
},
address: "0.0.0.0",
},
want: true,
},
{
name: "random port bound on 0.0.0.0",
args: args{
portProvider: func() (int, serverCloser, error) {
portProvider: func(address string) (int, serverCloser, error) {
// Intentionally not using httptest.Server, which listens to 127.0.0.1
l, err := net.Listen("tcp", "0.0.0.0:0")
l, err := net.Listen("tcp", fmt.Sprintf("%s:0", address))
if err != nil {
return 0, nil, err
}
Expand All @@ -2833,6 +2835,7 @@ func TestIsPortFree(t *testing.T) {
}
return port, s, nil
},
address: "0.0.0.0",
},
want: false,
},
Expand All @@ -2844,7 +2847,7 @@ func TestIsPortFree(t *testing.T) {
var s serverCloser
var err error
if tt.args.portProvider != nil {
port, s, err = tt.args.portProvider()
port, s, err = tt.args.portProvider(tt.args.address)
if s != nil {
defer s.Close()
}
Expand All @@ -2854,7 +2857,7 @@ func TestIsPortFree(t *testing.T) {
}
}

if got := IsPortFree(port); got != tt.want {
if got := IsPortFree(port, tt.args.address); got != tt.want {
t.Errorf("IsPortFree() = %v, want %v", got, tt.want)
}
})
Expand Down
22 changes: 18 additions & 4 deletions tests/helper/helper_dev.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package helper

import (
"fmt"
"os"
"regexp"
"time"
Expand Down Expand Up @@ -112,6 +113,7 @@ type DevSession struct {
session *gexec.Session
stopped bool
console *expect.Console
address string
}

type DevSessionOpts struct {
Expand All @@ -120,6 +122,7 @@ type DevSessionOpts struct {
RunOnPodman bool
TimeoutInSeconds int
NoRandomPorts bool
CustomAddress string
}

// StartDevMode starts a dev session with `odo dev`
Expand All @@ -139,6 +142,9 @@ func StartDevMode(options DevSessionOpts) (devSession DevSession, out []byte, er
if !options.NoRandomPorts {
args = append(args, "--random-ports")
}
if options.CustomAddress != "" {
args = append(args, "--address", options.CustomAddress)
}
args = append(args, options.CmdlineArgs...)
cmd := Cmd("odo", args...)
cmd.Cmd.Stdin = c.Tty()
Expand All @@ -154,6 +160,7 @@ func StartDevMode(options DevSessionOpts) (devSession DevSession, out []byte, er
result := DevSession{
session: session,
console: c,
address: options.CustomAddress,
}
outContents := session.Out.Contents()
errContents := session.Err.Contents()
Expand All @@ -165,7 +172,7 @@ func StartDevMode(options DevSessionOpts) (devSession DevSession, out []byte, er
if err != nil {
return DevSession{}, nil, nil, nil, err
}
return result, outContents, errContents, getPorts(string(outContents)), nil
return result, outContents, errContents, getPorts(string(outContents), options.CustomAddress), nil

}

Expand Down Expand Up @@ -242,7 +249,7 @@ func (o DevSession) GetInfo() ([]byte, []byte, map[string]string, error) {
if err != nil {
return nil, nil, nil, err
}
return outContents, errContents, getPorts(string(outContents)), nil
return outContents, errContents, getPorts(string(outContents), o.address), nil
}

func (o DevSession) CheckNotSynced(timeout time.Duration) {
Expand Down Expand Up @@ -279,6 +286,9 @@ func WaitForDevModeToContain(options DevSessionOpts, substring string, stopSessi
if options.RunOnPodman {
args = append(args, "--platform", "podman")
}
if options.CustomAddress != "" {
args = append(args, "--address", options.CustomAddress)
}
session := Cmd("odo", args...).AddEnv(options.EnvVars...).Runner().session
if checkErrOut {
WaitForErroutToContain(substring, 360, 10, session)
Expand All @@ -287,6 +297,7 @@ func WaitForDevModeToContain(options DevSessionOpts, substring string, stopSessi
}
result := DevSession{
session: session,
address: options.CustomAddress,
}
if stopSessionAfter {
defer func() {
Expand All @@ -311,9 +322,12 @@ func WaitForDevModeToContain(options DevSessionOpts, substring string, stopSessi
// getPorts returns a map of ports redirected depending on the information in s
//
// `- Forwarding from 127.0.0.1:20001 -> 3000` will return { "3000": "127.0.0.1:20001" }
func getPorts(s string) map[string]string {
func getPorts(s, address string) map[string]string {
if address == "" {
address = "127.0.0.1"
}
result := map[string]string{}
re := regexp.MustCompile("(127.0.0.1:[0-9]+) -> ([0-9]+)")
re := regexp.MustCompile(fmt.Sprintf("(%s:[0-9]+) -> ([0-9]+)", address))
matches := re.FindAllStringSubmatch(s, -1)
for _, match := range matches {
result[match[2]] = match[1]
Expand Down
1 change: 1 addition & 0 deletions tests/helper/helper_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package helper
import (
"crypto/tls"
"fmt"

"io"
"net/http"
"strconv"
Expand Down
Loading

0 comments on commit 5fa1b15

Please sign in to comment.