github.com/drud/ddev@v1.21.5-alpha1.0.20230226034409-94fcc4b94453/pkg/testcommon/testcommon_test.go (about)

     1  package testcommon
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/drud/ddev/pkg/ddevapp"
     6  	"github.com/drud/ddev/pkg/dockerutil"
     7  	"github.com/drud/ddev/pkg/exec"
     8  	"github.com/drud/ddev/pkg/globalconfig"
     9  	"github.com/drud/ddev/pkg/nodeps"
    10  	asrt "github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	"os"
    13  	"path/filepath"
    14  	"reflect"
    15  	"testing"
    16  )
    17  
    18  var DdevBin = "ddev"
    19  var TestSites = []TestSite{
    20  	{
    21  		SourceURL:                     "https://wordpress.org/wordpress-5.8.2.tar.gz",
    22  		ArchiveInternalExtractionPath: "wordpress/",
    23  		FilesTarballURL:               "https://github.com/drud/ddev_test_tarballs/releases/download/v1.1/wordpress5.8.2_files.tar.gz",
    24  		DBTarURL:                      "https://github.com/drud/ddev_test_tarballs/releases/download/v1.1/wordpress5.8.2_db.sql.tar.gz",
    25  		Docroot:                       "",
    26  		Type:                          nodeps.AppTypeWordPress,
    27  		Safe200URIWithExpectation:     URIWithExpect{URI: "/readme.html", Expect: "Welcome. WordPress is a very special project to me."},
    28  		DynamicURI:                    URIWithExpect{URI: "/", Expect: "this post has a photo"},
    29  		FilesImageURI:                 "/wp-content/uploads/2021/12/DSCF0436-randy-and-nancy-with-traditional-wedding-out-fit-2048x1536.jpg",
    30  		Name:                          "TestCmdWordpress",
    31  		HTTPProbeURI:                  "wp-admin/setup-config.php",
    32  	},
    33  }
    34  
    35  // TestCreateTmpDir tests the ability to create a temporary directory.
    36  func TestCreateTmpDir(t *testing.T) {
    37  	assert := asrt.New(t)
    38  
    39  	// Create a temporary directory and ensure it exists.
    40  	testDir := CreateTmpDir("TestCreateTmpDir")
    41  	dirStat, err := os.Stat(testDir)
    42  	assert.NoError(err, "There is no error when getting directory details")
    43  	assert.True(dirStat.IsDir(), "Temp Directory created and exists")
    44  
    45  	// Clean up temporary directory and ensure it no longer exists.
    46  	CleanupDir(testDir)
    47  	_, err = os.Stat(testDir)
    48  	assert.Error(err, "Could not stat temporary directory")
    49  	if err != nil {
    50  		assert.True(os.IsNotExist(err), "Error is of type IsNotExists")
    51  	}
    52  }
    53  
    54  // TestChdir tests the Chdir function and ensures it will change to a temporary directory and then properly return
    55  // to the original directory when cleaned up.
    56  func TestChdir(t *testing.T) {
    57  	assert := asrt.New(t)
    58  	// Get the current working directory.
    59  	startingDir, err := os.Getwd()
    60  	assert.NoError(err)
    61  
    62  	// Create a temporary directory.
    63  	testDir := CreateTmpDir("TestChdir")
    64  	assert.NotEqual(startingDir, testDir, "Ensure our starting directory and temporary directory are not the same")
    65  
    66  	// Change to the temporary directory.
    67  	cleanupFunc := Chdir(testDir)
    68  	currentDir, err := os.Getwd()
    69  	assert.NoError(err)
    70  
    71  	// On OSX this are created under /var, but /var is a symlink to /var/private, so we cannot ensure complete equality of these strings.
    72  	assert.Contains(currentDir, testDir, "Ensure the current directory is the temporary directory we created")
    73  	assert.True(reflect.TypeOf(cleanupFunc).Kind() == reflect.Func, "Chdir return is of type function")
    74  
    75  	cleanupFunc()
    76  	currentDir, err = os.Getwd()
    77  	assert.NoError(err)
    78  	assert.Equal(currentDir, startingDir, "Ensure we have changed back to the starting directory")
    79  
    80  	CleanupDir(testDir)
    81  }
    82  
    83  // TestValidTestSite tests the TestSite struct behavior in the case of a valid configuration.
    84  func TestValidTestSite(t *testing.T) {
    85  	assert := asrt.New(t)
    86  	// Get the current working directory.
    87  	startingDir, err := os.Getwd()
    88  	assert.NoError(err, "Could not get current directory.")
    89  
    90  	if os.Getenv("DDEV_BINARY_FULLPATH") != "" {
    91  		DdevBin = os.Getenv("DDEV_BINARY_FULLPATH")
    92  	}
    93  
    94  	// It's not ideal to copy/paste this archive around, but we don't actually care about the contents
    95  	// of the archive for this test, only that it exists and can be extracted. This should (knock on wood)
    96  	//not need to be updated over time.
    97  	site := TestSites[0]
    98  
    99  	// If running this with GOTEST_SHORT we have to create the directory, tarball etc.
   100  	site.Name = "TestValidTestSite"
   101  	_, _ = exec.RunCommand(DdevBin, []string{"stop", "-RO", site.Name})
   102  
   103  	//nolint: errcheck
   104  	defer exec.RunCommand(DdevBin, []string{"stop", "-RO", site.Name})
   105  	//nolint: errcheck
   106  	defer globalconfig.RemoveProjectInfo(site.Name)
   107  	err = site.Prepare()
   108  	require.NoError(t, err, "Prepare() failed on TestSite.Prepare() site=%s, err=%v", site.Name, err)
   109  
   110  	assert.NotNil(site.Dir, "Directory is set.")
   111  	docroot := filepath.Join(site.Dir, site.Docroot)
   112  	dirStat, err := os.Stat(docroot)
   113  	assert.NoError(err, "Docroot exists after prepare()")
   114  	if err != nil {
   115  		t.Fatalf("Directory did not exist after prepare(): %s", docroot)
   116  	}
   117  	assert.True(dirStat.IsDir(), "Docroot is a directory")
   118  
   119  	cleanup := site.Chdir()
   120  	defer cleanup()
   121  
   122  	currentDir, err := os.Getwd()
   123  	assert.NoError(err)
   124  
   125  	// On OSX this are created under /var, but /var is a symlink to /var/private, so we cannot ensure complete equality of these strings.
   126  	assert.Contains(currentDir, site.Dir)
   127  
   128  	cleanup()
   129  
   130  	currentDir, err = os.Getwd()
   131  	assert.NoError(err)
   132  	assert.Equal(startingDir, currentDir)
   133  
   134  	site.Cleanup()
   135  	_, err = os.Stat(site.Dir)
   136  	assert.Error(err, "Could not stat temporary directory after cleanup")
   137  }
   138  
   139  // TestGetLocalHTTPResponse() brings up a project and hits a URL to get the response
   140  func TestGetLocalHTTPResponse(t *testing.T) {
   141  	//if runtime.GOOS == "windows" || nodeps.IsMacM1() || dockerutil.IsColima() {
   142  	//	t.Skip("Skipping on Windows/Mac M1/Colima as we always seem to have port conflicts")
   143  	//}
   144  	// We have to get globalconfig read so CA is known and installed.
   145  	err := globalconfig.ReadGlobalConfig()
   146  	require.NoError(t, err)
   147  
   148  	assert := asrt.New(t)
   149  
   150  	dockerutil.EnsureDdevNetwork()
   151  
   152  	if os.Getenv("DDEV_BINARY_FULLPATH") != "" {
   153  		DdevBin = os.Getenv("DDEV_BINARY_FULLPATH")
   154  	}
   155  
   156  	// It's not ideal to copy/paste this archive around, but we don't actually care about the contents
   157  	// of the archive for this test, only that it exists and can be extracted. This should (knock on wood)
   158  	//not need to be updated over time.
   159  	site := TestSites[0]
   160  	site.Name = t.Name()
   161  
   162  	_, _ = exec.RunCommand(DdevBin, []string{"stop", "-RO", site.Name})
   163  	//nolint: errcheck
   164  	defer exec.RunCommand(DdevBin, []string{"stop", "-RO", site.Name})
   165  	//nolint: errcheck
   166  	defer globalconfig.RemoveProjectInfo(site.Name)
   167  
   168  	err = site.Prepare()
   169  	require.NoError(t, err, "Prepare() failed on TestSite.Prepare() site=%s, err=%v", site.Name, err)
   170  
   171  	cleanup := site.Chdir()
   172  	defer cleanup()
   173  
   174  	app := &ddevapp.DdevApp{}
   175  	err = app.Init(site.Dir)
   176  	assert.NoError(err)
   177  	// nolint: errcheck
   178  	defer app.Stop(true, false)
   179  
   180  	for _, pair := range []PortPair{{"8000", "8043"}, {"8080", "8443"}} {
   181  		ClearDockerEnv()
   182  		app.RouterHTTPPort = pair.HTTPPort
   183  		app.RouterHTTPSPort = pair.HTTPSPort
   184  		err = app.WriteConfig()
   185  		assert.NoError(err)
   186  
   187  		startErr := app.StartAndWait(5)
   188  		assert.NoError(startErr, "app.StartAndWait failed for port pair %v", pair)
   189  		if startErr != nil {
   190  			logs, _ := ddevapp.GetErrLogsFromApp(app, startErr)
   191  			t.Fatalf("logs from broken container:\n=======\n%s\n========\n", logs)
   192  		}
   193  
   194  		safeURL := app.GetHTTPURL() + site.Safe200URIWithExpectation.URI
   195  
   196  		// Extra dummy GetLocalHTTPResponse is for mac M1 to try to prime it.
   197  		_, _, _ = GetLocalHTTPResponse(t, safeURL, 60)
   198  		out, _, err := GetLocalHTTPResponse(t, safeURL, 60)
   199  		assert.NoError(err)
   200  		assert.Contains(out, site.Safe200URIWithExpectation.Expect)
   201  
   202  		// Skip the https version if we don't have mkcert working
   203  		if globalconfig.GetCAROOT() != "" {
   204  			safeURL = app.GetHTTPSURL() + site.Safe200URIWithExpectation.URI
   205  			out, _, err = GetLocalHTTPResponse(t, safeURL, 60)
   206  			assert.NoError(err)
   207  			assert.Contains(out, site.Safe200URIWithExpectation.Expect)
   208  			// This does the same thing as previous, but worth exercising it here.
   209  			_, _ = EnsureLocalHTTPContent(t, safeURL, site.Safe200URIWithExpectation.Expect)
   210  		}
   211  	}
   212  	// Set the ports back to the default was so we don't break any following tests.
   213  	app.RouterHTTPSPort = "443"
   214  	app.RouterHTTPPort = "80"
   215  	err = app.WriteConfig()
   216  	assert.NoError(err)
   217  
   218  	err = app.Stop(true, false)
   219  	assert.NoError(err)
   220  
   221  	cleanup()
   222  
   223  	site.Cleanup()
   224  }
   225  
   226  // TestGetCachedArchive tests download and extraction of archives for test sites
   227  // to testcache directory.
   228  func TestGetCachedArchive(t *testing.T) {
   229  	assert := asrt.New(t)
   230  
   231  	sourceURL := "https://raw.githubusercontent.com/drud/ddev/master/.gitignore"
   232  	exPath, archPath, err := GetCachedArchive("TestInvalidArchive", "test", "", sourceURL)
   233  	assert.Error(err)
   234  	if err != nil {
   235  		assert.Contains(err.Error(), fmt.Sprintf("archive extraction of %s failed", archPath))
   236  	}
   237  
   238  	err = os.RemoveAll(filepath.Dir(exPath))
   239  	assert.NoError(err)
   240  
   241  	sourceURL = "http://invalid_domain/somefilethatdoesnotexists"
   242  	exPath, archPath, err = GetCachedArchive("TestInvalidDownloadURL", "test", "", sourceURL)
   243  	assert.Error(err)
   244  	if err != nil {
   245  		assert.Contains(err.Error(), fmt.Sprintf("Failed to download url=%s into %s", sourceURL, archPath))
   246  	}
   247  
   248  	err = os.RemoveAll(filepath.Dir(exPath))
   249  	assert.NoError(err)
   250  }