github.com/mponton/terratest@v0.44.0/modules/files/files_test.go (about)

     1  package files
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  const copyFolderContentsFixtureRoot = "../../test/fixtures/copy-folder-contents"
    15  
    16  func TestFileExists(t *testing.T) {
    17  	t.Parallel()
    18  
    19  	currentFile, err := filepath.Abs(os.Args[0])
    20  	require.NoError(t, err)
    21  
    22  	assert.True(t, FileExists(currentFile))
    23  	assert.False(t, FileExists("/not/a/real/path"))
    24  }
    25  
    26  func TestIsExistingFile(t *testing.T) {
    27  	t.Parallel()
    28  
    29  	currentFile, err := filepath.Abs(os.Args[0])
    30  	require.NoError(t, err)
    31  	currentFileDir := filepath.Dir(currentFile)
    32  
    33  	assert.True(t, IsExistingFile(currentFile))
    34  	assert.False(t, IsExistingFile("/not/a/real/path"))
    35  	assert.False(t, IsExistingFile(currentFileDir))
    36  }
    37  
    38  func TestIsExistingDir(t *testing.T) {
    39  	t.Parallel()
    40  
    41  	currentFile, err := filepath.Abs(os.Args[0])
    42  	require.NoError(t, err)
    43  	currentFileDir := filepath.Dir(currentFile)
    44  
    45  	assert.False(t, IsExistingDir(currentFile))
    46  	assert.False(t, IsExistingDir("/not/a/real/path"))
    47  	assert.True(t, IsExistingDir(currentFileDir))
    48  }
    49  
    50  func TestCopyFolderToDest(t *testing.T) {
    51  	t.Parallel()
    52  
    53  	tempFolderPrefix := "someprefix"
    54  	destFolder := os.TempDir()
    55  	tmpDir := t.TempDir()
    56  
    57  	filter := func(path string) bool {
    58  		return !PathContainsHiddenFileOrFolder(path) && !PathContainsTerraformState(path)
    59  	}
    60  
    61  	folder, err := CopyFolderToDest("/not/a/real/path", destFolder, tempFolderPrefix, filter)
    62  	require.Error(t, err)
    63  	assert.False(t, FileExists(folder))
    64  
    65  	folder, err = CopyFolderToDest(tmpDir, destFolder, tempFolderPrefix, filter)
    66  	assert.DirExists(t, folder)
    67  	assert.NoError(t, err)
    68  }
    69  
    70  func TestCopyFolderContents(t *testing.T) {
    71  	t.Parallel()
    72  
    73  	originalDir := filepath.Join(copyFolderContentsFixtureRoot, "original")
    74  	expectedDir := filepath.Join(copyFolderContentsFixtureRoot, "full-copy")
    75  	tmpDir := t.TempDir()
    76  
    77  	err := CopyFolderContents(originalDir, tmpDir)
    78  	require.NoError(t, err)
    79  
    80  	requireDirectoriesEqual(t, expectedDir, tmpDir)
    81  }
    82  
    83  func TestCopyFolderContentsWithHiddenFilesFilter(t *testing.T) {
    84  	t.Parallel()
    85  
    86  	originalDir := filepath.Join(copyFolderContentsFixtureRoot, "original")
    87  	expectedDir := filepath.Join(copyFolderContentsFixtureRoot, "no-hidden-files")
    88  	tmpDir := t.TempDir()
    89  
    90  	err := CopyFolderContentsWithFilter(originalDir, tmpDir, func(path string) bool {
    91  		return !PathContainsHiddenFileOrFolder(path)
    92  	})
    93  	require.NoError(t, err)
    94  
    95  	requireDirectoriesEqual(t, expectedDir, tmpDir)
    96  }
    97  
    98  // Test copying a folder that contains symlinks
    99  func TestCopyFolderContentsWithSymLinks(t *testing.T) {
   100  	t.Parallel()
   101  
   102  	originalDir := filepath.Join(copyFolderContentsFixtureRoot, "symlinks")
   103  	expectedDir := filepath.Join(copyFolderContentsFixtureRoot, "symlinks")
   104  	tmpDir := t.TempDir()
   105  
   106  	err := CopyFolderContentsWithFilter(originalDir, tmpDir, func(path string) bool {
   107  		return !PathContainsHiddenFileOrFolder(path)
   108  	})
   109  	require.NoError(t, err)
   110  
   111  	requireDirectoriesEqual(t, expectedDir, tmpDir)
   112  }
   113  
   114  // Test copying a folder that contains symlinks that point to a non-existent file
   115  func TestCopyFolderContentsWithBrokenSymLinks(t *testing.T) {
   116  	t.Parallel()
   117  
   118  	// Creating broken symlink
   119  	pathToFile := filepath.Join(copyFolderContentsFixtureRoot, "symlinks-broken/nonexistent-folder/bar.txt")
   120  	pathToSymlink := filepath.Join(copyFolderContentsFixtureRoot, "symlinks-broken/bar.txt")
   121  	defer func() {
   122  		if err := os.Remove(pathToSymlink); err != nil {
   123  			t.Fatal(fmt.Errorf("Failed to remove link: %+v", err))
   124  		}
   125  	}()
   126  	if err := os.Symlink(pathToFile, pathToSymlink); err != nil {
   127  		t.Fatal(fmt.Errorf("Failed to create broken link for test: %+v", err))
   128  	}
   129  
   130  	// Test copying folder
   131  	originalDir := filepath.Join(copyFolderContentsFixtureRoot, "symlinks-broken")
   132  	tmpDir := t.TempDir()
   133  
   134  	err := CopyFolderContentsWithFilter(originalDir, tmpDir, func(path string) bool {
   135  		return !PathContainsHiddenFileOrFolder(path)
   136  	})
   137  	require.NoError(t, err)
   138  
   139  	// This requireDirectoriesEqual command uses GNU diff under the hood, but unfortunately we cannot instruct diff to
   140  	// compare symlinks in two directories without attempting to dereference any symlinks until diff version 3.3.0.
   141  	// Because many environments are still using diff < 3.3.0, we disregard this test for now.
   142  	// Per https://unix.stackexchange.com/a/119406/129208
   143  	//requireDirectoriesEqual(t, expectedDir, tmpDir)
   144  	fmt.Println("Test completed without error, however due to a limitation in GNU diff < 3.3.0, directories have not been compared for equivalency.")
   145  }
   146  
   147  func TestCopyTerraformFolderToTemp(t *testing.T) {
   148  	t.Parallel()
   149  
   150  	originalDir := filepath.Join(copyFolderContentsFixtureRoot, "original")
   151  	expectedDir := filepath.Join(copyFolderContentsFixtureRoot, "no-hidden-files-no-terraform-files")
   152  
   153  	tmpDir, err := CopyTerraformFolderToTemp(originalDir, "TestCopyTerraformFolderToTemp")
   154  	require.NoError(t, err)
   155  
   156  	requireDirectoriesEqual(t, expectedDir, tmpDir)
   157  }
   158  
   159  func TestCopyTerraformFolderToDest(t *testing.T) {
   160  	t.Parallel()
   161  
   162  	originalDir := filepath.Join(copyFolderContentsFixtureRoot, "original")
   163  	expectedDir := filepath.Join(copyFolderContentsFixtureRoot, "no-hidden-files-no-terraform-files")
   164  	destFolder := os.TempDir()
   165  
   166  	tmpDir, err := CopyTerraformFolderToDest(originalDir, destFolder, "TestCopyTerraformFolderToTemp")
   167  	require.NoError(t, err)
   168  
   169  	requireDirectoriesEqual(t, expectedDir, tmpDir)
   170  }
   171  
   172  func TestCopyTerragruntFolderToTemp(t *testing.T) {
   173  	t.Parallel()
   174  
   175  	originalDir := filepath.Join(copyFolderContentsFixtureRoot, "terragrunt-files")
   176  	expectedDir := filepath.Join(copyFolderContentsFixtureRoot, "no-state-files")
   177  
   178  	tmpDir, err := CopyTerragruntFolderToTemp(originalDir, t.Name())
   179  	require.NoError(t, err)
   180  
   181  	requireDirectoriesEqual(t, expectedDir, tmpDir)
   182  }
   183  
   184  func TestCopyTerragruntFolderToDest(t *testing.T) {
   185  	t.Parallel()
   186  
   187  	originalDir := filepath.Join(copyFolderContentsFixtureRoot, "terragrunt-files")
   188  	expectedDir := filepath.Join(copyFolderContentsFixtureRoot, "no-state-files")
   189  	destFolder := os.TempDir()
   190  
   191  	tmpDir, err := CopyTerragruntFolderToDest(originalDir, destFolder, t.Name())
   192  	require.NoError(t, err)
   193  
   194  	requireDirectoriesEqual(t, expectedDir, tmpDir)
   195  }
   196  
   197  func TestPathContainsTerraformStateOrVars(t *testing.T) {
   198  	var data = []struct {
   199  		desc     string
   200  		path     string
   201  		contains bool
   202  	}{
   203  		{"contains tfvars", "./folder/terraform.tfvars", true},
   204  		{"contains tfvars.json", "./folder/hello/terraform.tfvars.json", true},
   205  		{"contains state", "./folder/hello/helloagain/terraform.tfstate", true},
   206  		{"contains state backup", "./folder/hey/terraform.tfstate.backup", true},
   207  		{"does not contain any", "./folder/salut/terraform.json", false},
   208  	}
   209  
   210  	for _, tt := range data {
   211  		tt := tt
   212  		t.Run(tt.desc, func(t *testing.T) {
   213  			result := PathContainsTerraformStateOrVars(tt.path)
   214  			if result != tt.contains {
   215  				if tt.contains {
   216  					t.Errorf("Expected %s to contain Terraform related file", tt.path)
   217  				} else {
   218  					t.Errorf("Expected %s to not contain Terraform related file", tt.path)
   219  				}
   220  			}
   221  		})
   222  	}
   223  }
   224  
   225  // Diffing two directories to ensure they have the exact same files, contents, etc and showing exactly what's different
   226  // takes a lot of code. Why waste time on that when this functionality is already nicely implemented in the Unix/Linux
   227  // "diff" command? We shell out to that command at test time.
   228  func requireDirectoriesEqual(t *testing.T, folderWithExpectedContents string, folderWithActualContents string) {
   229  	cmd := exec.Command("diff", "-r", "-u", folderWithExpectedContents, folderWithActualContents)
   230  
   231  	bytes, err := cmd.Output()
   232  	output := string(bytes)
   233  
   234  	require.NoError(t, err, "diff command exited with an error. This likely means the contents of %s and %s are different. Here is the output of the diff command:\n%s", folderWithExpectedContents, folderWithActualContents, output)
   235  }