github.com/hashicorp/packer@v1.14.3/packer_test/common/fs.go (about)

     1  package common
     2  
     3  import (
     4  	"crypto/sha256"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  	"runtime"
    10  	"testing"
    11  )
    12  
    13  // CopyFile essentially replicates the `cp` command, for a file only.
    14  //
    15  // # Permissions are copied over from the source to destination
    16  //
    17  // The function detects if destination is a directory or a file (existent or not).
    18  //
    19  // If this is the former, we append the source file's basename to the
    20  // directory and create the file from that inferred path.
    21  func CopyFile(t *testing.T, dest, src string) {
    22  	st, err := os.Stat(src)
    23  	if err != nil {
    24  		t.Fatalf("failed to stat origin file %q: %s", src, err)
    25  	}
    26  
    27  	// If the stat call fails, we assume dest is the destination file.
    28  	dstStat, err := os.Stat(dest)
    29  	if err == nil && dstStat.IsDir() {
    30  		dest = filepath.Join(dest, filepath.Base(src))
    31  	}
    32  
    33  	destFD, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, st.Mode().Perm())
    34  	if err != nil {
    35  		t.Fatalf("failed to create cp destination file %q: %s", dest, err)
    36  	}
    37  	defer destFD.Close()
    38  
    39  	srcFD, err := os.Open(src)
    40  	if err != nil {
    41  		t.Fatalf("failed to open source file to copy: %s", err)
    42  	}
    43  	defer srcFD.Close()
    44  
    45  	_, err = io.Copy(destFD, srcFD)
    46  	if err != nil {
    47  		t.Fatalf("failed to copy from %q -> %q: %s", src, dest, err)
    48  	}
    49  }
    50  
    51  // WriteFile writes `content` to a file `dest`
    52  //
    53  // The default permissions of that file is 0644
    54  func WriteFile(t *testing.T, dest string, content string) {
    55  	outFile, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
    56  	if err != nil {
    57  		t.Fatalf("failed to open/create %q: %s", dest, err)
    58  	}
    59  	defer outFile.Close()
    60  
    61  	_, err = fmt.Fprintf(outFile, "%s", content)
    62  	if err != nil {
    63  		t.Fatalf("failed to write to file %q: %s", dest, err)
    64  	}
    65  }
    66  
    67  // TempWorkdir creates a working directory for a Packer test with the list of files
    68  // given as input.
    69  //
    70  // The files should either have a path relative to the test that invokes it, or should
    71  // be absolute.
    72  // Each file will be copied to the root of the workdir being created.
    73  //
    74  // If any file cannot be found, this function will fail
    75  func TempWorkdir(t *testing.T, files ...string) (string, func()) {
    76  	var err error
    77  	tempDir, err := os.MkdirTemp("", "packer-test-workdir-")
    78  	if err != nil {
    79  		t.Fatalf("failed to create temporary working directory: %s", err)
    80  	}
    81  
    82  	defer func() {
    83  		if err != nil {
    84  			os.RemoveAll(tempDir)
    85  			t.Errorf("failed to create temporary workdir: %s", err)
    86  		}
    87  	}()
    88  
    89  	for _, file := range files {
    90  		CopyFile(t, tempDir, file)
    91  	}
    92  
    93  	return tempDir, func() {
    94  		err := os.RemoveAll(tempDir)
    95  		if err != nil {
    96  			t.Logf("failed to remove temporary workdir %q: %s. This will need manual action.", tempDir, err)
    97  		}
    98  	}
    99  }
   100  
   101  // SHA256Sum computes the SHA256 digest for an input file
   102  //
   103  // The digest is returned as a hexstring
   104  func SHA256Sum(t *testing.T, file string) string {
   105  	fl, err := os.ReadFile(file)
   106  	if err != nil {
   107  		t.Fatalf("failed to compute sha256sum for %q: %s", file, err)
   108  	}
   109  	sha := sha256.New()
   110  	sha.Write(fl)
   111  	return fmt.Sprintf("%x", sha.Sum([]byte{}))
   112  }
   113  
   114  // currentDir returns the directory in which the current file is located.
   115  //
   116  // Since we're in tests it's reliable as they're supposed to run on the same
   117  // machine the binary's compiled from, but goes to say it's not meant for use
   118  // in distributed binaries.
   119  func currentDir() (string, error) {
   120  	// pc uintptr, file string, line int, ok bool
   121  	_, testDir, _, ok := runtime.Caller(0)
   122  	if !ok {
   123  		return "", fmt.Errorf("couldn't get the location of the test suite file")
   124  	}
   125  
   126  	return filepath.Dir(testDir), nil
   127  }