github.com/apache/incubator-kie-tools/packages/kn-plugin-workflow@v0.28.1-0.20240311201729-34c6856b157f/e2e-tests/main_test.go (about)

     1  //go:build e2e_tests
     2  
     3  /*
     4   * Licensed to the Apache Software Foundation (ASF) under one
     5   * or more contributor license agreements.  See the NOTICE file
     6   * distributed with this work for additional information
     7   * regarding copyright ownership.  The ASF licenses this file
     8   * to you under the Apache License, Version 2.0 (the
     9   * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *  http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21  
    22  package e2e_tests
    23  
    24  import (
    25  	"flag"
    26  	"fmt"
    27  	"os"
    28  	"path/filepath"
    29  	"runtime"
    30  	"strings"
    31  	"testing"
    32  	"time"
    33  )
    34  
    35  var parentPath string
    36  var TempTestsPath string
    37  var KnExecutable string
    38  
    39  var TestPrintCmdOutput = flag.Bool("logs", true, "Print command output during tests")
    40  
    41  func TestMain(m *testing.M) {
    42  
    43  	// Create temp directory for tests and switch inside it
    44  	workingPath, _ := os.Getwd()
    45  	parentPath = filepath.Dir(workingPath)
    46  	tempDirName := "temp-tests"
    47  	if fileExists(tempDirName) {
    48  		cleanUpTemp(workingPath, tempDirName)
    49  	}
    50  	setUpTempDir(tempDirName)
    51  	TempTestsPath = filepath.Join(workingPath, tempDirName)
    52  
    53  	KnExecutable = getPlatformSpecificExecutablePath()
    54  
    55  	checkAndBuildExecutable()
    56  
    57  	// Run tests
    58  	exitCode := m.Run()
    59  
    60  	// Cleanup after tests
    61  	cleanUpTemp(workingPath, tempDirName)
    62  
    63  	os.Exit(exitCode)
    64  }
    65  
    66  func setUpTempDir(tempDirName string) {
    67  	var err error
    68  	err = os.Mkdir(tempDirName, 0750)
    69  	if err != nil {
    70  		fmt.Printf("Failed to create temp directory: %v", err)
    71  		os.Exit(1)
    72  	}
    73  	err = os.Chdir(tempDirName)
    74  	if err != nil {
    75  		fmt.Printf("Failed to change directory to temp: %v", err)
    76  		os.Exit(1)
    77  	}
    78  }
    79  
    80  func cleanUpTemp(workingPath string, tempDirName string) {
    81  	var err error
    82  	err = os.Chdir(workingPath)
    83  	if err != nil {
    84  		fmt.Printf("Failed to change directory back from temp: %v", err)
    85  		os.Exit(1)
    86  	}
    87  	err = os.RemoveAll(tempDirName)
    88  	if err != nil {
    89  		fmt.Printf("Failed to remove temp directory: %v", err)
    90  		os.Exit(1)
    91  	}
    92  }
    93  
    94  func getPlatformSpecificExecutablePath() string {
    95  	binaryDirPath := filepath.Join(parentPath, "dist")
    96  	buildOutput := filepath.Join(binaryDirPath, "/kn-workflow-")
    97  	switch osAndArch := strings.ToLower(runtime.GOOS); osAndArch {
    98  	case "darwin":
    99  		switch arch := strings.ToLower(runtime.GOARCH); arch {
   100  		case "amd64":
   101  			buildOutput += "darwin-amd64"
   102  		case "arm64":
   103  			buildOutput += "darwin-arm64"
   104  		default:
   105  			fmt.Println("Unsupported architecture:", arch)
   106  			os.Exit(1)
   107  		}
   108  	case "linux":
   109  		buildOutput += "linux-amd64"
   110  	case "windows":
   111  		switch arch := strings.ToLower(runtime.GOARCH); arch {
   112  		case "amd64":
   113  			buildOutput += "windows-amd64.exe"
   114  		default:
   115  			fmt.Println("Unsupported architecture:", arch)
   116  			os.Exit(1)
   117  		}
   118  	default:
   119  		fmt.Println("Unsupported OS:", osAndArch)
   120  		os.Exit(1)
   121  	}
   122  	return buildOutput
   123  }
   124  
   125  func checkAndBuildExecutable() {
   126  	// Check if rebuilding the executable is needed
   127  	executableExists := fileExists(KnExecutable)
   128  	executableIsExecutable := isExecAny(KnExecutable)
   129  	lastBuildTimestamp, errTimestamp := getDistFolderTimestamp(filepath.Join(parentPath, "dist"))
   130  	codeModified, errModified := areSourceFilesModifiedSince(lastBuildTimestamp)
   131  	if executableExists == false || executableIsExecutable == false || codeModified == true || errTimestamp != nil || errModified != nil {
   132  		buildDev() // Build the executable for current platform (`build:dev`)
   133  	}
   134  }
   135  
   136  func getDistFolderTimestamp(path string) (time.Time, error) {
   137  	fileInfo, err := os.Stat(path)
   138  	if err != nil {
   139  		return time.Time{}, err
   140  	}
   141  
   142  	return fileInfo.ModTime(), nil
   143  }
   144  
   145  func areSourceFilesModifiedSince(timestamp time.Time) (bool, error) {
   146  	excludedFolders := []string{"e2e-tests", "dist-tests", "dist"}
   147  	modificationsDetected := false
   148  
   149  	err := filepath.Walk(parentPath, func(path string, info os.FileInfo, err error) error {
   150  		if err != nil {
   151  			return err
   152  		}
   153  
   154  		if info.IsDir() {
   155  			for _, excludedFolder := range excludedFolders {
   156  				if strings.Contains(path, excludedFolder) {
   157  					return filepath.SkipDir
   158  				}
   159  			}
   160  			return nil
   161  		}
   162  
   163  		modifiedTime := info.ModTime()
   164  		if modifiedTime.After(timestamp) {
   165  			modificationsDetected = true
   166  			return filepath.SkipDir
   167  		}
   168  
   169  		return nil
   170  	})
   171  
   172  	if err != nil {
   173  		return false, err
   174  	}
   175  
   176  	return modificationsDetected, nil
   177  }
   178  
   179  func buildDev() {
   180  	err := ExecuteCommand("pnpm", "build:dev")
   181  	if err != nil {
   182  		fmt.Println("Failed to build:", err)
   183  		os.Exit(1)
   184  	}
   185  
   186  	err = ExecuteCommand("chmod", "+x", KnExecutable)
   187  	if err != nil {
   188  		fmt.Println("Failed to make the built executable file executable:", err)
   189  		os.Exit(1)
   190  	}
   191  
   192  	return
   193  }
   194  
   195  func fileExists(filePath string) bool {
   196  	_, err := os.Stat(filePath)
   197  	return err == nil
   198  }
   199  
   200  func isExecAny(filePath string) bool {
   201  	fileInfo, _ := os.Stat(filePath)
   202  	fileMode := fileInfo.Mode()
   203  	return fileMode&0111 != 0
   204  }