chore: clean up e2e project update logic (#1593)

* chore: clean up e2e project update logic

Signed-off-by: Matej Vasek <mvasek@redhat.com>

* fixup: linter unused param

Signed-off-by: Matej Vasek <mvasek@redhat.com>

---------

Signed-off-by: Matej Vasek <mvasek@redhat.com>
This commit is contained in:
Matej Vasek 2023-03-02 20:14:31 +01:00 committed by GitHub
parent 850adf30ab
commit 1cff3a4d35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 51 additions and 10937 deletions

View File

@ -1,5 +0,0 @@
module function
go 1.14
require github.com/cloudevents/sdk-go/v2 v2.4.0

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
{
"name": "event-handler",
"version": "0.1.0",
"description": "Node.js CloudEvent Handler",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": ""
},
"scripts": {
"test": "node test/unit.js && node test/integration.js",
"start": "faas-js-runtime index.js",
"debug": "nodemon --inspect ./node_modules/faas-js-runtime/bin/cli.js index.js"
},
"devDependencies": {
"nodemon": "^2.0.4",
"supertest": "^4.0.2",
"tape": "^4.13.0"
},
"dependencies": {
"cloudevents": "^4.0.3",
"faas-js-runtime": "^0.7.1"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +0,0 @@
{
"name": "http-handler",
"version": "0.1.0",
"description": "A function which responds to HTTP requests",
"main": "index.js",
"scripts": {
"test": "node test/unit.js && node test/integration.js",
"start": "faas-js-runtime index.js",
"debug": "nodemon --inspect ./node_modules/faas-js-runtime/bin/cli.js index.js"
},
"keywords": [],
"author": "",
"license": "Apache-2.0",
"dependencies": {
"faas-js-runtime": "^0.7.1"
},
"devDependencies": {
"nodemon": "^2.0.4",
"supertest": "^4.0.2",
"tape": "^5.0.1"
}
}

View File

@ -1 +0,0 @@
web: python -m parliament .

View File

@ -1 +0,0 @@
parliament-functions==0.1.0

View File

@ -1,19 +0,0 @@
package functions;
public class Input {
private String message;
public Input() {}
public Input(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -1,19 +0,0 @@
package functions;
public class Output {
private String message;
public Output() {}
public Output(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -1,6 +0,0 @@
# Configuration file
# key = value
quarkus.funqy.export=function
quarkus.smallrye-health.root-path=/health
quarkus.smallrye-health.liveness-path=liveness
quarkus.smallrye-health.readiness-path=readiness

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +0,0 @@
{
"name": "event-handler",
"version": "0.1.0",
"description": "TypeScript HTTP Handler",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": ""
},
"scripts": {
"build": "npx -p typescript tsc",
"start": "faas-js-runtime ./build/index.js"
},
"devDependencies": {
"@types/tape": "^4.13.0",
"nodemon": "^2.0.4",
"tape": "^4.13.0",
"ts-node": "^9.1.1",
"typescript": "^4.2.4"
},
"dependencies": {
"@types/node": "^15.3.0",
"cloudevents": "^4.0.2",
"faas-js-runtime": "^0.7.1"
}
}

View File

@ -1,5 +1,5 @@
import { Context, Invokable } from 'faas-js-runtime';
export const handle: Invokable = function (context: Context): string {
export const handle: Invokable = function (_: Context): string {
return 'HELLO TYPESCRIPT FUNCTION';
};
};

View File

@ -1,22 +0,0 @@
{
"include": [
"src/**/*"
],
"exclude": ["node_modules"],
"compilerOptions": {
"target": "ES2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"outDir": "./build", /* Redirect output structure to the directory. */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
"strictNullChecks": true, /* Enable strict null checks. */
"strictFunctionTypes": true, /* Enable strict checking of function types. */
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
"noUnusedLocals": true, /* Report errors on unused locals. */
"noUnusedParameters": false, /* Report errors on unused parameters. */
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}

View File

@ -1,7 +1,9 @@
package e2e
import (
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"testing"
@ -26,7 +28,7 @@ func Update(t *testing.T, knFunc *TestShellCmdRunner, project *FunctionTestProje
// Template folder exists for given runtime / template.
// Let's update the project and redeploy
err := projectUpdaterFor(project).UpdateFolderContent(t, templatePath, project)
err := UpdateFolderContent(t, templatePath, project)
if err != nil {
t.Fatal("an error has occurred while updating project folder with new sources.", err.Error())
}
@ -43,130 +45,57 @@ func Update(t *testing.T, knFunc *TestShellCmdRunner, project *FunctionTestProje
project.IsNewRevision = true
}
// projectUpdater offers methods to update the project source content by the
// source provided on update_templates folder
// The strategy used consists in
// 1. Create a temporary project folder with some files from original test folder (such as func.yaml, pom.xml)
// 2. Copy recursivelly all files from ./update_template/<runtime>/<template>/** to the temporary project folder
// 3. Replace current project folder by the temporary one (rm -rf <project folder> && mv <tmp folder> <project folder>
type projectUpdater struct {
retainList []string // List of files to retain from original test project
}
func projectUpdaterFor(project *FunctionTestProject) projectUpdater {
updater := projectUpdater{retainList: []string{"func.yaml"}}
if project.Runtime == "springboot" {
updater.retainList = append(updater.retainList, "pom.xml")
}
if project.Runtime == "quarkus" {
updater.retainList = append(updater.retainList, "pom.xml")
}
return updater
}
func (p projectUpdater) UpdateFolderContent(t *testing.T, templatePath string, project *FunctionTestProject) error {
// Create temp project folder (reuse func.yaml)
projectTmp := NewFunctionTestProject(t, project.Runtime, project.Template)
projectTmp.ProjectPath = projectTmp.ProjectPath + "-tmp"
err := projectTmp.CreateProjectFolder()
if err != nil {
return err
}
defer func() {
_ = projectTmp.RemoveProjectFolder()
}()
// Copy files to retain (let's reuse some such as func.yaml, pom.xml)
for _, sourceFile := range p.retainList {
targetDir := filepath.Join(projectTmp.ProjectPath, filepath.Dir(sourceFile))
_, err = os.Stat(targetDir)
if err != nil && os.IsNotExist(err) {
err = os.MkdirAll(targetDir, os.ModePerm)
if err != nil {
return err
}
}
err = p.copyFile(filepath.Join(project.ProjectPath, sourceFile), filepath.Join(projectTmp.ProjectPath, sourceFile))
// UpdateFolderContent overwrites content of project.ProjectPath with content of updatedPath.
// Similar to `cp -a {updatedPath}/* {project.ProjectPath}/`.
func UpdateFolderContent(t *testing.T, updatedPath string, project *FunctionTestProject) error {
// overwrite files with updated ones
buff := make([]byte, 4096)
return filepath.Walk(updatedPath, func(srcPath string, srcFi fs.FileInfo, err error) error {
if err != nil {
return err
return fmt.Errorf("walk error: %w", err)
}
relPath, err := filepath.Rel(updatedPath, srcPath)
if err != nil {
return fmt.Errorf("canot get rel path: %w", err)
}
}
// Copy from template structure to new project folders and files
err = p.walkThru(templatePath, func(path string, f os.FileInfo) error {
var err error = nil
if !f.IsDir() {
if templatePath == path { // root path
err = p.copyFile(filepath.Join(templatePath, f.Name()), filepath.Join(projectTmp.ProjectPath, f.Name()))
} else {
// Create dir if not exists
relativePath, _ := filepath.Rel(templatePath, path)
targetDir := filepath.Join(projectTmp.ProjectPath, relativePath)
_, err = os.Stat(targetDir)
if err != nil && os.IsNotExist(err) {
err = os.MkdirAll(targetDir, os.ModePerm)
if err != nil {
return err
}
destPath := filepath.Join(project.ProjectPath, relPath)
destFi, err := os.Lstat(destPath)
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("cannot lstat dest file: %w", err)
}
if destFi != nil && destFi.Mode().Type() != srcFi.Mode().Type() {
return fmt.Errorf("dest file already exist but type is not matching")
}
switch srcFi.Mode().Type() {
case 0:
var dest, src *os.File
dest, err = os.OpenFile(destPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, srcFi.Mode().Perm())
if err != nil {
return fmt.Errorf("cannot open dest file: %w", err)
}
defer dest.Close()
src, err = os.Open(srcPath)
if err != nil {
return fmt.Errorf("cannot open src file: %w", err)
}
defer src.Close()
_, err = io.CopyBuffer(dest, src, buff)
if err != nil {
return fmt.Errorf("cannot copy file: %w", err)
}
case fs.ModeDir:
if destFi == nil {
err = os.MkdirAll(destPath, 0755)
if err != nil {
return fmt.Errorf("cannot create dir: %w", err)
}
err = p.copyFile(filepath.Join(templatePath, relativePath, f.Name()), filepath.Join(targetDir, f.Name()))
}
default:
return fmt.Errorf("unspuported type: %s", srcFi.Mode().Type())
}
return err
return nil
})
if err != nil {
return err
}
// Replace project folder
err = project.RemoveProjectFolder()
if err != nil {
return err
}
return os.Rename(projectTmp.ProjectPath, project.ProjectPath)
}
// walkThru recursive visit files in the filesystem and invokes fn for each of them
// it can be replaced in future by filepath.WalkDir when project moves to 1.16+)
func (p projectUpdater) walkThru(dir string, fn func(path string, f os.FileInfo) error) error {
files, err := os.ReadDir(dir)
if err != nil {
return err
}
for _, file := range files {
fileInfo, err := file.Info()
if err != nil {
return err
}
err = fn(dir, fileInfo)
if err != nil {
return err
}
if file.IsDir() {
err := p.walkThru(filepath.Join(dir, file.Name()), fn)
if err != nil {
return err
}
}
}
return nil
}
func (p projectUpdater) copyFile(sourceFile string, destFile string) error {
_, err := os.Stat(sourceFile)
if err != nil {
return err
}
src, err := os.Open(sourceFile)
if err != nil {
return err
}
defer src.Close()
dst, err := os.Create(destFile)
if err != nil {
return err
}
defer dst.Close()
_, err = io.Copy(dst, src)
return err
}