mirror of https://github.com/knative/func.git
				
				
				
			
		
			
				
	
	
		
			184 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
//go:build e2e
 | 
						|
 | 
						|
package e2e
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"net"
 | 
						|
	"path/filepath"
 | 
						|
	"regexp"
 | 
						|
	"strings"
 | 
						|
	"syscall"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"gotest.tools/v3/assert"
 | 
						|
	"knative.dev/func/test/oncluster"
 | 
						|
	"knative.dev/func/test/testhttp"
 | 
						|
 | 
						|
	common "knative.dev/func/test/common"
 | 
						|
)
 | 
						|
 | 
						|
// TestFunctionExtendedFlow will run a comprehensive path of func commands an end user may perform such as
 | 
						|
// > create > build > run > (curl)+invoke > deploy > describe > list > (curl)+invoke > deploy (new revision) > (curl) > delete > list
 | 
						|
func TestFunctionExtendedFlow(t *testing.T) {
 | 
						|
 | 
						|
	var funcName = "extended-test"
 | 
						|
	var funcPath = filepath.Join(t.TempDir(), funcName)
 | 
						|
 | 
						|
	knFunc := common.NewKnFuncShellCli(t)
 | 
						|
	knFunc.ShouldDumpOnSuccess = false
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Func Create Test
 | 
						|
	// ---------------------------
 | 
						|
	knFunc.Exec("create", "--language", "node", funcPath)
 | 
						|
 | 
						|
	// From here on, all commands will be executed from the func project path
 | 
						|
	knFunc.SourceDir = funcPath
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Func Build Test
 | 
						|
	// ---------------------------
 | 
						|
	knFunc.Exec("build", "--registry", common.GetRegistry())
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Func Run Test
 | 
						|
	// ---------------------------
 | 
						|
	knFuncTerm1 := common.NewKnFuncShellCli(t)
 | 
						|
	knFuncTerm1.ShouldDumpOnSuccess = false
 | 
						|
	knFuncTerm2 := common.NewKnFuncShellCli(t)
 | 
						|
	knFuncTerm2.ShouldDumpOnSuccess = true
 | 
						|
 | 
						|
	portChannel := make(chan string)
 | 
						|
	go func() {
 | 
						|
		t.Log("----Checking for listening port")
 | 
						|
		// set the function that will be executed while "kn func run" is executed
 | 
						|
		knFuncTerm1.OnWaitCallback = func(stdout *bytes.Buffer) {
 | 
						|
			t.Log("-----Executing OnWaitCallback")
 | 
						|
			funcPort, attempts := "", 0
 | 
						|
			for funcPort == "" && attempts < 10 {
 | 
						|
				t.Logf("----Function Output:\n%v\n", stdout.String())
 | 
						|
				findPort := func(exp string, msg string) (port string) {
 | 
						|
					matches := regexp.MustCompile(exp).FindStringSubmatch(msg)
 | 
						|
					if len(matches) > 1 {
 | 
						|
						port = matches[1]
 | 
						|
					}
 | 
						|
					return
 | 
						|
				}
 | 
						|
				funcPort = findPort("Running on host port (.*)", stdout.String())
 | 
						|
				if funcPort == "" {
 | 
						|
					funcPort = findPort("Function started on port (.*)", stdout.String())
 | 
						|
				}
 | 
						|
				attempts++
 | 
						|
				if funcPort == "" {
 | 
						|
					time.Sleep(200 * time.Millisecond)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			// can proceed
 | 
						|
			portChannel <- funcPort
 | 
						|
		}
 | 
						|
		knFuncTerm1.Exec("run", "--verbose", "--path", funcPath)
 | 
						|
	}()
 | 
						|
 | 
						|
	knFuncRunCompleted := false
 | 
						|
	knFuncRunProcessFinalizer := func() {
 | 
						|
		if knFuncRunCompleted == false {
 | 
						|
			knFuncTerm1.ExecCmd.Process.Signal(syscall.SIGTERM)
 | 
						|
			knFuncRunCompleted = true
 | 
						|
		}
 | 
						|
	}
 | 
						|
	defer knFuncRunProcessFinalizer()
 | 
						|
 | 
						|
	// Get running port (usually 8080) from func output. We can use it for test http.
 | 
						|
	funcPort := <-portChannel
 | 
						|
	assert.Assert(t, funcPort != "", "Unable to retrieve local port allocated for function")
 | 
						|
 | 
						|
	// Wait Port to be available
 | 
						|
	net.DialTimeout("tcp", ":"+funcPort, 3*time.Second)
 | 
						|
	time.Sleep(time.Second)
 | 
						|
 | 
						|
	// GET Function HTTP Endpoint
 | 
						|
	_, bodyResp := testhttp.TestGet(t, "http://localhost:"+funcPort+"?message=local")
 | 
						|
	assert.Assert(t, strings.Contains(bodyResp, `{"message":"local"}`), "function response does not contain expected body.")
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Func Invoke Locally Test
 | 
						|
	// ---------------------------
 | 
						|
	result := knFuncTerm2.Exec("invoke", "--path", funcPath)
 | 
						|
	assert.Assert(t, strings.Contains(result.Out, `{"message":"Hello World"}`), "function response does not contain expected body.")
 | 
						|
 | 
						|
	// Stop "kn func run" execution
 | 
						|
	knFuncRunProcessFinalizer()
 | 
						|
	time.Sleep(2 * time.Second)
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Func Deploy Test
 | 
						|
	// ---------------------------
 | 
						|
	knFuncDelete := func(t *testing.T) {
 | 
						|
		knFunc.Exec("delete", funcName)
 | 
						|
		listResult := knFunc.Exec("list")
 | 
						|
		assert.Assert(t, strings.Contains(listResult.Out, funcName) == false, "Function is listed as deployed after delete")
 | 
						|
	}
 | 
						|
 | 
						|
	result = knFunc.Exec("deploy", "--build=false")
 | 
						|
	firstRevisionName, functionUrl := common.WaitForFunctionReady(t, funcName)
 | 
						|
	defer knFuncDelete(t)
 | 
						|
 | 
						|
	wasDeployed := regexp.MustCompile("✅ Function [a-z]* in namespace .* at URL: \n   http.*").MatchString(result.Out)
 | 
						|
	assert.Assert(t, wasDeployed, "Function was not deployed")
 | 
						|
 | 
						|
	urlFromDeploy := ""
 | 
						|
	matches := regexp.MustCompile("URL: \n   (http.*)").FindStringSubmatch(result.Out)
 | 
						|
	if len(matches) > 1 {
 | 
						|
		urlFromDeploy = matches[1]
 | 
						|
	}
 | 
						|
	assert.Assert(t, urlFromDeploy != "", "URL not returned on deploy output")
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Func Describe Test
 | 
						|
	// ---------------------------
 | 
						|
	urlFromDescribe := ""
 | 
						|
	result = knFunc.Exec("describe", "--output", "plain")
 | 
						|
	matches = regexp.MustCompile("Route (http.*)").FindStringSubmatch(result.Out)
 | 
						|
	if len(matches) > 1 {
 | 
						|
		urlFromDescribe = matches[1]
 | 
						|
	}
 | 
						|
	assert.Assert(t, urlFromDescribe != "", "URL not returned on info output")
 | 
						|
	assert.Assert(t, urlFromDescribe == urlFromDeploy, fmt.Sprintf("URL from 'func info' [%s] does not match URL from 'func deploy' [%s]", urlFromDescribe, urlFromDeploy))
 | 
						|
	assert.Assert(t, urlFromDescribe == functionUrl, "URL does not match knative service URL")
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Func List Test
 | 
						|
	// ---------------------------
 | 
						|
	result = knFunc.Exec("list")
 | 
						|
	assert.Assert(t, strings.Contains(result.Out, funcName), "deployed function is not listed")
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Invoke Remote Test
 | 
						|
	// ---------------------------
 | 
						|
	result = knFunc.Exec("invoke")
 | 
						|
	assert.Assert(t, strings.Contains(result.Out, `{"message":"Hello World"}`), "function response does not contain expected body.")
 | 
						|
 | 
						|
	// GET Function HTTP Endpoint
 | 
						|
	_, bodyResp = testhttp.TestGet(t, functionUrl+"?message=remote")
 | 
						|
	assert.Assert(t, strings.Contains(bodyResp, `{"message":"remote"}`), "function response does not contain expected body.")
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Deploy new revision
 | 
						|
	// ---------------------------
 | 
						|
	oncluster.WriteNewSimpleIndexJS(t, funcPath, "NEW_REVISION")
 | 
						|
	knFunc.Exec("deploy")
 | 
						|
 | 
						|
	common.WaitForNewRevisionReady(t, firstRevisionName, funcName)
 | 
						|
 | 
						|
	// ---------------------------
 | 
						|
	// Call New Revision
 | 
						|
	// ---------------------------
 | 
						|
	_, bodyResp = testhttp.TestGet(t, functionUrl)
 | 
						|
	assert.Assert(t, strings.Contains(bodyResp, "NEW_REVISION"), "function new revision does not contain expected body.")
 | 
						|
 | 
						|
	// Delete Test (on defer)
 | 
						|
}
 |