How to use GetApps method of regression Package

Best Keploy code snippet using regression.GetApps

ddevapp_test.go

Source:ddevapp_test.go Github

copy

Full Screen

...714 if err != nil {715 assert.Contains(err.Error(), "Could not find a project")716 }717}718// TestGetApps tests the GetActiveProjects function to ensure it accurately returns a list of running applications.719func TestGetApps(t *testing.T) {720 assert := asrt.New(t)721 // Start the apps.722 for _, site := range TestSites {723 testcommon.ClearDockerEnv()724 app := &ddevapp.DdevApp{}725 err := app.Init(site.Dir)726 assert.NoError(err)727 err = app.Start()728 assert.NoError(err)729 }730 apps := ddevapp.GetActiveProjects()731 for _, testSite := range TestSites {732 var found bool733 for _, app := range apps {734 if testSite.Name == app.GetName() {735 found = true736 break737 }738 }739 assert.True(found, "Found testSite %s in list", testSite.Name)740 }741 // Now shut down all sites as we expect them to be shut down.742 for _, site := range TestSites {743 testcommon.ClearDockerEnv()744 app := &ddevapp.DdevApp{}745 err := app.Init(site.Dir)746 assert.NoError(err)747 err = app.Stop(true, false)748 assert.NoError(err)749 }750}751// TestDdevImportDB tests the functionality that is called when "ddev import-db" is executed752func TestDdevImportDB(t *testing.T) {753 assert := asrt.New(t)754 app := &ddevapp.DdevApp{}755 testDir, _ := os.Getwd()756 site := TestSites[0]757 switchDir := site.Chdir()758 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s %s", site.Name, t.Name()))759 testcommon.ClearDockerEnv()760 err := app.Init(site.Dir)761 assert.NoError(err)762 err = app.Start()763 assert.NoError(err)764 defer func() {765 app.Hooks = nil766 _ = app.WriteConfig()767 _ = app.Stop(true, false)768 }()769 _, _, err = app.Exec(&ddevapp.ExecOpts{770 Service: "db",771 Cmd: "mysql -N -e 'DROP DATABASE IF EXISTS test;'",772 })773 assert.NoError(err)774 app.Hooks = map[string][]ddevapp.YAMLTask{"post-import-db": {{"exec-host": "touch hello-post-import-db-" + app.Name}}, "pre-import-db": {{"exec-host": "touch hello-pre-import-db-" + app.Name}}}775 // Test simple db loads.776 for _, file := range []string{"users.sql", "users.mysql", "users.sql.gz", "users.mysql.gz", "users.sql.tar", "users.mysql.tar", "users.sql.tar.gz", "users.mysql.tar.gz", "users.sql.tgz", "users.mysql.tgz", "users.sql.zip", "users.mysql.zip", "users_with_USE_statement.sql"} {777 path := filepath.Join(testDir, "testdata", t.Name(), file)778 err = app.ImportDB(path, "", false, false, "db")779 assert.NoError(err, "Failed to app.ImportDB path: %s err: %v", path, err)780 if err != nil {781 continue782 }783 // There should be exactly the one users table for each of these files784 out, _, err := app.Exec(&ddevapp.ExecOpts{785 Service: "db",786 Cmd: "mysql -N -e 'SHOW TABLES;' | cat",787 })788 assert.NoError(err)789 assert.Equal("users\n", out)790 // Verify that no extra database was created791 out, _, err = app.Exec(&ddevapp.ExecOpts{792 Service: "db",793 Cmd: `mysql -N -e 'SHOW DATABASES;' | egrep -v "^(information_schema|performance_schema|mysql)$"`,794 })795 assert.NoError(err)796 assert.Equal("db\n", out)797 // Test that a settings file has correct hash_salt format798 switch app.Type {799 case nodeps.AppTypeDrupal7:800 drupalHashSalt, err := fileutil.FgrepStringInFile(app.SiteDdevSettingsFile, "$drupal_hash_salt")801 assert.NoError(err)802 assert.True(drupalHashSalt)803 case nodeps.AppTypeDrupal8:804 settingsHashSalt, err := fileutil.FgrepStringInFile(app.SiteDdevSettingsFile, "settings['hash_salt']")805 assert.NoError(err)806 assert.True(settingsHashSalt)807 case nodeps.AppTypeWordPress:808 hasAuthSalt, err := fileutil.FgrepStringInFile(app.SiteSettingsPath, "SECURE_AUTH_SALT")809 assert.NoError(err)810 assert.True(hasAuthSalt)811 }812 }813 if site.DBTarURL != "" {814 _, cachedArchive, err := testcommon.GetCachedArchive(site.Name, site.Name+"_siteTarArchive", "", site.DBTarURL)815 assert.NoError(err)816 err = app.ImportDB(cachedArchive, "", false, false, "db")817 assert.NoError(err)818 assert.FileExists("hello-pre-import-db-" + app.Name)819 assert.FileExists("hello-post-import-db-" + app.Name)820 err = os.Remove("hello-pre-import-db-" + app.Name)821 assert.NoError(err)822 err = os.Remove("hello-post-import-db-" + app.Name)823 assert.NoError(err)824 }825 if site.DBZipURL != "" {826 _, cachedArchive, err := testcommon.GetCachedArchive(site.Name, site.Name+"_siteZipArchive", "", site.DBZipURL)827 assert.NoError(err)828 err = app.ImportDB(cachedArchive, "", false, false, "db")829 assert.NoError(err)830 assert.FileExists("hello-pre-import-db-" + app.Name)831 assert.FileExists("hello-post-import-db-" + app.Name)832 _ = os.RemoveAll("hello-pre-import-db-" + app.Name)833 _ = os.RemoveAll("hello-post-import-db-" + app.Name)834 }835 if site.FullSiteTarballURL != "" {836 _, cachedArchive, err := testcommon.GetCachedArchive(site.Name, site.Name+"_FullSiteTarballURL", "", site.FullSiteTarballURL)837 assert.NoError(err)838 err = app.ImportDB(cachedArchive, "data.sql", false, false, "db")839 assert.NoError(err, "Failed to find data.sql at root of tarball %s", cachedArchive)840 assert.FileExists("hello-pre-import-db-" + app.Name)841 assert.FileExists("hello-post-import-db-" + app.Name)842 _ = os.RemoveAll("hello-pre-import-db-" + app.Name)843 _ = os.RemoveAll("hello-post-import-db-" + app.Name)844 }845 app.Hooks = nil846 for _, db := range []string{"db", "extradb"} {847 // Import from stdin, make sure that works848 inputFile := filepath.Join(testDir, "testdata", t.Name(), "stdintable.sql")849 f, err := os.Open(inputFile)850 require.NoError(t, err)851 // nolint: errcheck852 defer f.Close()853 savedStdin := os.Stdin854 os.Stdin = f855 err = app.ImportDB("", "", false, false, db)856 os.Stdin = savedStdin857 assert.NoError(err)858 out, _, err := app.Exec(&ddevapp.ExecOpts{859 Service: "db",860 Cmd: fmt.Sprintf(`echo "SHOW DATABASES LIKE '%s'; SELECT COUNT(*) FROM stdintable;" | mysql -N %s`, db, db),861 })862 assert.NoError(err)863 assert.Equal(out, fmt.Sprintf("%s\n2\n", db))864 // Import 2-user users.sql into users table865 path := filepath.Join(testDir, "testdata", t.Name(), "users.sql")866 err = app.ImportDB(path, "", false, false, db)867 assert.NoError(err)868 out, stderr, err := app.Exec(&ddevapp.ExecOpts{869 Service: "db",870 Cmd: fmt.Sprintf(`echo "SELECT COUNT(*) AS TOTALNUMBEROFTABLES FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s';" | mysql -N %s`, db, db),871 })872 assert.NoError(err, "exec failed: %v", stderr)873 assert.Equal("1\n", out)874 // Import 1-user sql and make sure only one row is left there875 path = filepath.Join(testDir, "testdata", t.Name(), "oneuser.sql")876 err = app.ImportDB(path, "", false, false, db)877 assert.NoError(err)878 out, _, err = app.Exec(&ddevapp.ExecOpts{879 Service: "db",880 Cmd: fmt.Sprintf(`echo "SELECT COUNT(*) AS TOTALNUMBEROFTABLES FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s';" | mysql -N %s`, db, db),881 })882 assert.NoError(err)883 assert.Equal("1\n", out)884 // Import 2-user users.sql again, but with nodrop=true885 // We should end up with 2 tables now886 path = filepath.Join(testDir, "testdata", t.Name(), "users.sql")887 err = app.ImportDB(path, "", false, true, db)888 assert.NoError(err)889 out, _, err = app.Exec(&ddevapp.ExecOpts{890 Service: "db",891 Cmd: fmt.Sprintf(`echo "SELECT COUNT(*) AS TOTALNUMBEROFTABLES FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s';" | mysql -N %s`, db, db),892 })893 assert.NoError(err)894 assert.Equal("2\n", out)895 }896 runTime()897 switchDir()898}899// TestDdevAllDatabases tests db import/export/start with all MariaDB versions900func TestDdevAllDatabases(t *testing.T) {901 assert := asrt.New(t)902 dbVersions := map[string]map[string]bool{903 "mariadb": nodeps.ValidMariaDBVersions,904 "mysql": nodeps.ValidMySQLVersions,905 }906 //Use a smaller list if GOTEST_SHORT907 if os.Getenv("GOTEST_SHORT") != "" {908 t.Log("Using limited set of database servers because GOTEST_SHORT is set")909 dbVersions = map[string]map[string]bool{910 "mariadb": {nodeps.MariaDB102: true, nodeps.MariaDB103: true},911 }912 // If we have any mysql, limit what we test (but there may not be any)913 if len(dbVersions["mysql"]) != 0 {914 dbVersions["mysql"] = map[string]bool{nodeps.MySQL80: true, nodeps.MySQL56: true}915 }916 }917 app := &ddevapp.DdevApp{}918 testDir, _ := os.Getwd()919 site := TestSites[0]920 switchDir := site.Chdir()921 defer switchDir()922 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s %s", site.Name, t.Name()))923 testcommon.ClearDockerEnv()924 err := app.Init(site.Dir)925 assert.NoError(err)926 // Make sure there isn't an old db laying around927 _ = dockerutil.RemoveVolume(app.Name + "-mariadb")928 //nolint: errcheck929 defer func() {930 _ = app.Stop(true, false)931 // Make sure we leave the config.yaml in expected state932 app.MariaDBVersion = ""933 app.MySQLVersion = ""934 app.DBImage = ""935 _ = app.WriteConfig()936 }()937 for dbType, versions := range dbVersions {938 for v := range versions {939 t.Logf("testing db server functionality of %v:%v", dbType, v)940 _ = app.Stop(true, false)941 if dbType == "mariadb" {942 app.MySQLVersion = ""943 app.MariaDBVersion = v944 } else if dbType == "mysql" {945 app.MariaDBVersion = ""946 app.MySQLVersion = v947 }948 app.DBImage = ""949 _ = app.WriteConfig()950 startErr := app.Start()951 if startErr != nil {952 appLogs, err := ddevapp.GetErrLogsFromApp(app, startErr)953 assert.NoError(err)954 t.Fatalf("app.Start() failure %v; logs:\n=====\n%s\n=====\n", startErr, appLogs)955 }956 // Make sure the version of db running matches expected957 containerDBVersion, _, _ := app.Exec(&ddevapp.ExecOpts{958 Service: "db",959 Cmd: "cat /var/lib/mysql/db_mariadb_version.txt",960 })961 assert.Equal(v, strings.Trim(containerDBVersion, "\n\r "))962 importPath := filepath.Join(testDir, "testdata", t.Name(), "users.sql")963 err = app.ImportDB(importPath, "", false, false, "db")964 assert.NoError(err, "failed to import %v", importPath)965 _ = os.Mkdir("tmp", 0777)966 err = fileutil.PurgeDirectory("tmp")967 assert.NoError(err)968 // Test that we can export-db to a gzipped file969 err = app.ExportDB("tmp/users1.sql.gz", true, "db")970 assert.NoError(err)971 // Validate contents972 err = archive.Ungzip("tmp/users1.sql.gz", "tmp")973 assert.NoError(err)974 stringFound, err := fileutil.FgrepStringInFile("tmp/users1.sql", "Table structure for table `users`")975 assert.NoError(err)976 assert.True(stringFound)977 err = fileutil.PurgeDirectory("tmp")978 assert.NoError(err)979 // Export to an ungzipped file and validate980 err = app.ExportDB("tmp/users2.sql", false, "db")981 assert.NoError(err)982 // Validate contents983 stringFound, err = fileutil.FgrepStringInFile("tmp/users2.sql", "Table structure for table `users`")984 assert.NoError(err)985 assert.True(stringFound)986 err = fileutil.PurgeDirectory("tmp")987 assert.NoError(err)988 // Capture to stdout without gzip compression989 stdout := util.CaptureStdOut()990 err = app.ExportDB("", false, "db")991 assert.NoError(err)992 out := stdout()993 assert.Contains(out, "Table structure for table `users`")994 snapshotName := v + "_" + fileutil.RandomFilenameBase()995 output, err := app.Snapshot(snapshotName)996 assert.NoError(err, "could not create snapshot %s for version %s: %v output=%v", snapshotName, v, err, output)997 err = app.RestoreSnapshot(snapshotName)998 assert.NoError(err, "could not restore snapshot %s for version %s: %v", snapshotName, v, err)999 // Make sure the version of db running matches expected1000 containerDBVersion, _, _ = app.Exec(&ddevapp.ExecOpts{1001 Service: "db",1002 Cmd: "cat /var/lib/mysql/db_mariadb_version.txt",1003 })1004 assert.Equal(v, strings.Trim(containerDBVersion, "\n\r "))1005 // TODO: Restore a snapshot from a different version note warning.1006 _ = app.Stop(true, false)1007 }1008 }1009 runTime()1010}1011// TestDdevExportDB tests the functionality that is called when "ddev export-db" is executed1012func TestDdevExportDB(t *testing.T) {1013 assert := asrt.New(t)1014 app := &ddevapp.DdevApp{}1015 testDir, _ := os.Getwd()1016 site := TestSites[0]1017 switchDir := site.Chdir()1018 defer switchDir()1019 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s DdevExportDB", site.Name))1020 testcommon.ClearDockerEnv()1021 err := app.Init(site.Dir)1022 assert.NoError(err)1023 err = app.Start()1024 assert.NoError(err)1025 //nolint: errcheck1026 defer app.Stop(true, false)1027 importPath := filepath.Join(testDir, "testdata", t.Name(), "users.sql")1028 err = app.ImportDB(importPath, "", false, false, "db")1029 require.NoError(t, err)1030 _ = os.Mkdir("tmp", 0777)1031 // Most likely reason for failure is it exists, so let that go1032 err = fileutil.PurgeDirectory("tmp")1033 assert.NoError(err)1034 // Test that we can export-db to a gzipped file1035 err = app.ExportDB("tmp/users1.sql.gz", true, "db")1036 assert.NoError(err)1037 // Validate contents1038 err = archive.Ungzip("tmp/users1.sql.gz", "tmp")1039 assert.NoError(err)1040 stringFound, err := fileutil.FgrepStringInFile("tmp/users1.sql", "Table structure for table `users`")1041 assert.NoError(err)1042 assert.True(stringFound)1043 err = fileutil.PurgeDirectory("tmp")1044 assert.NoError(err)1045 // Export to an ungzipped file and validate1046 err = app.ExportDB("tmp/users2.sql", false, "db")1047 assert.NoError(err)1048 // Validate contents1049 stringFound, err = fileutil.FgrepStringInFile("tmp/users2.sql", "Table structure for table `users`")1050 assert.NoError(err)1051 assert.True(stringFound)1052 err = fileutil.PurgeDirectory("tmp")1053 assert.NoError(err)1054 // Capture to stdout without gzip compression1055 stdout := util.CaptureStdOut()1056 err = app.ExportDB("", false, "db")1057 assert.NoError(err)1058 output := stdout()1059 assert.Contains(output, "Table structure for table `users`")1060 // Export an alternate database1061 importPath = filepath.Join(testDir, "testdata", t.Name(), "users.sql")1062 err = app.ImportDB(importPath, "", false, false, "anotherdb")1063 require.NoError(t, err)1064 err = app.ExportDB("tmp/anotherdb.sql.gz", true, "anotherdb")1065 assert.NoError(err)1066 importPath = "tmp/anotherdb.sql.gz"1067 err = app.ImportDB(importPath, "", false, false, "thirddb")1068 assert.NoError(err)1069 out, _, err := app.Exec(&ddevapp.ExecOpts{1070 Service: "db",1071 Cmd: fmt.Sprintf(`echo "SELECT COUNT(*) FROM users;" | mysql -N thirddb`),1072 })1073 assert.NoError(err)1074 assert.Equal("2\n", out)1075 runTime()1076}1077// TestDdevFullSiteSetup tests a full import-db and import-files and then looks to see if1078// we have a spot-test success hit on a URL1079func TestDdevFullSiteSetup(t *testing.T) {1080 assert := asrt.New(t)1081 app := &ddevapp.DdevApp{}1082 for _, site := range TestSites {1083 switchDir := site.Chdir()1084 defer switchDir()1085 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s DdevFullSiteSetup", site.Name))1086 t.Logf("=== BEGIN TestDdevFullSiteSetup for %s\n", site.Name)1087 testcommon.ClearDockerEnv()1088 err := app.Init(site.Dir)1089 assert.NoError(err)1090 // Get files before start, as syncing can start immediately.1091 if site.FilesTarballURL != "" {1092 _, tarballPath, err := testcommon.GetCachedArchive(site.Name, "local-tarballs-files", "", site.FilesTarballURL)1093 assert.NoError(err)1094 err = app.ImportFiles(tarballPath, "")1095 assert.NoError(err)1096 }1097 // Running WriteConfig assures that settings.ddev.php gets written1098 // so Drupal 8 won't try to set things unwriteable1099 err = app.WriteConfig()1100 assert.NoError(err)1101 err = app.Start()1102 assert.NoError(err)1103 // Validate PHPMyAdmin is working and database named db is present1104 _, _ = testcommon.EnsureLocalHTTPContent(t, app.GetHTTPURL()+":8036/tbl_create.php?server=1&db=db", "Table name:")1105 // Validate MailHog is working and "connected"1106 _, _ = testcommon.EnsureLocalHTTPContent(t, app.GetHTTPURL()+":8025/#", "Connected")1107 settingsLocation, err := app.DetermineSettingsPathLocation()1108 assert.NoError(err)1109 if app.Type != nodeps.AppTypeShopware6 {1110 assert.Equal(filepath.Dir(settingsLocation), filepath.Dir(app.SiteSettingsPath))1111 }1112 if nodeps.ArrayContainsString([]string{"drupal6", "drupal7"}, app.Type) {1113 assert.FileExists(filepath.Join(filepath.Dir(app.SiteSettingsPath), "drushrc.php"))1114 }1115 if site.DBTarURL != "" {1116 _, cachedArchive, err := testcommon.GetCachedArchive(site.Name, site.Name+"_siteTarArchive", "", site.DBTarURL)1117 assert.NoError(err)1118 err = app.ImportDB(cachedArchive, "", false, false, "db")1119 assert.NoError(err, "failed to import-db with dbtarball %s, app.Type=%s, mariadb_version=%s, mysql_version=%s", site.DBTarURL, app.Type, app.MariaDBVersion, app.MySQLVersion)1120 }1121 startErr := app.StartAndWait(2)1122 if startErr != nil {1123 appLogs, getLogsErr := ddevapp.GetErrLogsFromApp(app, startErr)1124 assert.NoError(getLogsErr)1125 t.Fatalf("app.StartAndWait() failure err=%v; logs:\n=====\n%s\n=====\n", startErr, appLogs)1126 }1127 // Test static content.1128 _, _ = testcommon.EnsureLocalHTTPContent(t, app.GetHTTPSURL()+site.Safe200URIWithExpectation.URI, site.Safe200URIWithExpectation.Expect)1129 // Test dynamic php + database content.1130 rawurl := app.GetHTTPSURL() + site.DynamicURI.URI1131 body, resp, err := testcommon.GetLocalHTTPResponse(t, rawurl, 120)1132 assert.NoError(err, "GetLocalHTTPResponse returned err on project=%s rawurl %s, resp=%v: %v", site.Name, rawurl, resp, err)1133 if err != nil && strings.Contains(err.Error(), "container ") {1134 logs, err := ddevapp.GetErrLogsFromApp(app, err)1135 assert.NoError(err)1136 t.Fatalf("Logs after GetLocalHTTPResponse: %s", logs)1137 }1138 assert.Contains(body, site.DynamicURI.Expect, "expected %s on project %s", site.DynamicURI.Expect, site.Name)1139 // Load an image from the files section1140 if site.FilesImageURI != "" {1141 _, resp, err := testcommon.GetLocalHTTPResponse(t, app.GetHTTPSURL()+site.FilesImageURI)1142 assert.NoError(err, "failed ImageURI response on project %s", site.Name)1143 if err != nil && resp != nil {1144 assert.Equal("image/jpeg", resp.Header["Content-Type"][0])1145 }1146 }1147 // Make sure we can do a simple hit against the host-mount of web container.1148 _, _ = testcommon.EnsureLocalHTTPContent(t, app.GetWebContainerDirectHTTPURL()+site.Safe200URIWithExpectation.URI, site.Safe200URIWithExpectation.Expect)1149 // We don't want all the projects running at once.1150 err = app.Stop(true, false)1151 assert.NoError(err)1152 runTime()1153 switchDir()1154 }1155 fmt.Print()1156}1157// TestDdevRestoreSnapshot tests creating a snapshot and reverting to it. This runs with Mariadb 10.21158func TestDdevRestoreSnapshot(t *testing.T) {1159 assert := asrt.New(t)1160 testDir, _ := os.Getwd()1161 app := &ddevapp.DdevApp{}1162 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("TestDdevRestoreSnapshot"))1163 d7testerTest1Dump, err := filepath.Abs(filepath.Join("testdata", t.Name(), "restore_snapshot", "d7tester_test_1.sql.gz"))1164 assert.NoError(err)1165 d7testerTest2Dump, err := filepath.Abs(filepath.Join("testdata", t.Name(), "restore_snapshot", "d7tester_test_2.sql.gz"))1166 assert.NoError(err)1167 // Use d7 only for this test, the key thing is the database interaction1168 site := FullTestSites[2]1169 // If running this with GOTEST_SHORT we have to create the directory, tarball etc.1170 if site.Dir == "" || !fileutil.FileExists(site.Dir) {1171 err = site.Prepare()1172 require.NoError(t, err)1173 }1174 switchDir := site.Chdir()1175 defer switchDir()1176 testcommon.ClearDockerEnv()1177 err = app.Init(site.Dir)1178 require.NoError(t, err)1179 app.Hooks = map[string][]ddevapp.YAMLTask{"post-snapshot": {{"exec-host": "touch hello-post-snapshot-" + app.Name}}, "pre-snapshot": {{"exec-host": "touch hello-pre-snapshot-" + app.Name}}}1180 // First do regular start, which is good enough to get us to an ImportDB()1181 err = app.Start()1182 require.NoError(t, err)1183 //nolint: errcheck1184 defer app.Stop(true, false)1185 err = app.ImportDB(d7testerTest1Dump, "", false, false, "db")1186 require.NoError(t, err, "Failed to app.ImportDB path: %s err: %v", d7testerTest1Dump, err)1187 err = app.StartAndWait(2)1188 require.NoError(t, err, "app.Start() failed on site %s, err=%v", site.Name, err)1189 resp, ensureErr := testcommon.EnsureLocalHTTPContent(t, app.GetHTTPSURL(), "d7 tester test 1 has 1 node", 45)1190 assert.NoError(ensureErr)1191 if ensureErr != nil && strings.Contains(ensureErr.Error(), "container failed") {1192 logs, err := ddevapp.GetErrLogsFromApp(app, ensureErr)1193 assert.NoError(err)1194 t.Fatalf("container failed: logs:\n=======\n%s\n========\n", logs)1195 }1196 require.NotNil(t, resp)1197 if ensureErr != nil && resp.StatusCode != 200 {1198 logs, err := app.CaptureLogs("web", false, "")1199 assert.NoError(err)1200 t.Fatalf("EnsureLocalHTTPContent received %d. Resp=%v, web logs=\n========\n%s\n=========\n", resp.StatusCode, resp, logs)1201 }1202 // Make a snapshot of d7 tester test 11203 backupsDir := filepath.Join(app.GetConfigPath(""), "db_snapshots")1204 snapshotName, err := app.Snapshot("d7testerTest1")1205 assert.NoError(err)1206 assert.EqualValues(snapshotName, "d7testerTest1")1207 assert.True(fileutil.FileExists(filepath.Join(backupsDir, snapshotName, "xtrabackup_info")))1208 assert.FileExists("hello-pre-snapshot-" + app.Name)1209 assert.FileExists("hello-post-snapshot-" + app.Name)1210 err = os.Remove("hello-pre-snapshot-" + app.Name)1211 assert.NoError(err)1212 err = os.Remove("hello-post-snapshot-" + app.Name)1213 assert.NoError(err)1214 err = app.ImportDB(d7testerTest2Dump, "", false, false, "db")1215 assert.NoError(err, "Failed to app.ImportDB path: %s err: %v", d7testerTest2Dump, err)1216 _, _ = testcommon.EnsureLocalHTTPContent(t, app.GetHTTPSURL(), "d7 tester test 2 has 2 nodes", 45)1217 snapshotName, err = app.Snapshot("d7testerTest2")1218 assert.NoError(err)1219 assert.EqualValues(snapshotName, "d7testerTest2")1220 assert.True(fileutil.FileExists(filepath.Join(backupsDir, snapshotName, "xtrabackup_info")))1221 app.Hooks = map[string][]ddevapp.YAMLTask{"post-restore-snapshot": {{"exec-host": "touch hello-post-restore-snapshot-" + app.Name}}, "pre-restore-snapshot": {{"exec-host": "touch hello-pre-restore-snapshot-" + app.Name}}}1222 err = app.RestoreSnapshot("d7testerTest1")1223 assert.NoError(err)1224 assert.FileExists("hello-pre-restore-snapshot-" + app.Name)1225 assert.FileExists("hello-post-restore-snapshot-" + app.Name)1226 err = os.Remove("hello-pre-restore-snapshot-" + app.Name)1227 assert.NoError(err)1228 err = os.Remove("hello-post-restore-snapshot-" + app.Name)1229 assert.NoError(err)1230 _, _ = testcommon.EnsureLocalHTTPContent(t, app.GetHTTPSURL(), "d7 tester test 1 has 1 node", 45)1231 err = app.RestoreSnapshot("d7testerTest2")1232 assert.NoError(err)1233 body, resp, err := testcommon.GetLocalHTTPResponse(t, app.GetHTTPSURL(), 45)1234 assert.NoError(err, "GetLocalHTTPResponse returned err on rawurl %s: %v", app.GetHTTPSURL(), err)1235 assert.Contains(body, "d7 tester test 2 has 2 nodes")1236 if err != nil {1237 t.Logf("resp after timeout: %v", resp)1238 out, err := app.CaptureLogs("web", false, "")1239 assert.NoError(err)1240 t.Logf("web container logs after timeout: %s", out)1241 }1242 // Attempt a restore with a pre-mariadb_10.2 snapshot. It should fail and give a link.1243 oldSnapshotTarball, err := filepath.Abs(filepath.Join(testDir, "testdata", t.Name(), "restore_snapshot", "d7tester_test_1.snapshot_mariadb_10_1.tgz"))1244 assert.NoError(err)1245 err = archive.Untar(oldSnapshotTarball, filepath.Join(site.Dir, ".ddev", "db_snapshots"), "")1246 assert.NoError(err)1247 err = app.RestoreSnapshot("d7tester_test_1.snapshot_mariadb_10.1")1248 assert.Error(err)1249 assert.Contains(err.Error(), "is not compatible")1250 app.Hooks = nil1251 _ = app.WriteConfig()1252 err = app.Stop(true, false)1253 assert.NoError(err)1254 // TODO: Check behavior of ddev rm with snapshot, see if it has right stuff in it.1255 runTime()1256}1257// TestWriteableFilesDirectory tests to make sure that files created on host are writable on container1258// and files ceated in container are correct user on host.1259func TestWriteableFilesDirectory(t *testing.T) {1260 assert := asrt.New(t)1261 app := &ddevapp.DdevApp{}1262 site := TestSites[0]1263 switchDir := site.Chdir()1264 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s TestWritableFilesDirectory", site.Name))1265 testcommon.ClearDockerEnv()1266 err := app.Init(site.Dir)1267 assert.NoError(err)1268 err = app.StartAndWait(0)1269 assert.NoError(err)1270 uploadDir := app.GetUploadDir()1271 assert.NotEmpty(uploadDir)1272 // Use exec to touch a file in the container and see what the result is. Make sure it comes out with ownership1273 // making it writeable on the host.1274 filename := fileutil.RandomFilenameBase()1275 dirname := fileutil.RandomFilenameBase()1276 // Use path.Join for items on th container (linux) and filepath.Join for items on the host.1277 inContainerDir := path.Join(uploadDir, dirname)1278 onHostDir := filepath.Join(app.Docroot, inContainerDir)1279 // The container execution directory is dependent on the app type1280 switch app.Type {1281 case nodeps.AppTypeWordPress, nodeps.AppTypeTYPO3, nodeps.AppTypePHP:1282 inContainerDir = path.Join(app.Docroot, inContainerDir)1283 }1284 inContainerRelativePath := path.Join(inContainerDir, filename)1285 onHostRelativePath := path.Join(onHostDir, filename)1286 err = os.MkdirAll(onHostDir, 0775)1287 assert.NoError(err)1288 // Create a file in the directory to make sure it syncs1289 f, err := os.OpenFile(filepath.Join(onHostDir, "junk.txt"), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)1290 assert.NoError(err)1291 _ = f.Close()1292 _, _, createFileErr := app.Exec(&ddevapp.ExecOpts{1293 Service: "web",1294 Cmd: "echo 'content created inside container\n' >" + inContainerRelativePath,1295 })1296 assert.NoError(createFileErr)1297 // Now try to append to the file on the host.1298 // os.OpenFile() for append here fails if the file does not already exist.1299 f, err = os.OpenFile(onHostRelativePath, os.O_APPEND|os.O_WRONLY, 0660)1300 assert.NoError(err)1301 _, err = f.WriteString("this addition to the file was added on the host side")1302 assert.NoError(err)1303 _ = f.Close()1304 // Create a file on the host and see what the result is. Make sure we can not append/write to it in the container.1305 filename = fileutil.RandomFilenameBase()1306 dirname = fileutil.RandomFilenameBase()1307 inContainerDir = path.Join(uploadDir, dirname)1308 onHostDir = filepath.Join(app.Docroot, inContainerDir)1309 // The container execution directory is dependent on the app type1310 switch app.Type {1311 case nodeps.AppTypeWordPress, nodeps.AppTypeTYPO3, nodeps.AppTypePHP:1312 inContainerDir = path.Join(app.Docroot, inContainerDir)1313 }1314 inContainerRelativePath = path.Join(inContainerDir, filename)1315 onHostRelativePath = filepath.Join(onHostDir, filename)1316 err = os.MkdirAll(onHostDir, 0775)1317 assert.NoError(err)1318 f, err = os.OpenFile(onHostRelativePath, os.O_CREATE|os.O_RDWR, 0660)1319 assert.NoError(err)1320 _, err = f.WriteString("this base content was inserted on the host side\n")1321 assert.NoError(err)1322 _ = f.Close()1323 // if the file exists, add to it. We don't want to add if it's not already there.1324 _, _, err = app.Exec(&ddevapp.ExecOpts{1325 Service: "web",1326 Cmd: "if [ -f " + inContainerRelativePath + " ]; then echo 'content added inside container\n' >>" + inContainerRelativePath + "; fi",1327 })1328 assert.NoError(err)1329 // grep the file for both the content added on host and that added in container.1330 _, _, err = app.Exec(&ddevapp.ExecOpts{1331 Service: "web",1332 Cmd: "grep 'base content was inserted on the host' " + inContainerRelativePath + "&& grep 'content added inside container' " + inContainerRelativePath,1333 })1334 assert.NoError(err)1335 err = app.Stop(true, false)1336 assert.NoError(err)1337 runTime()1338 switchDir()1339}1340// TestDdevImportFilesDir tests that "ddev import-files" can successfully import non-archive directories1341func TestDdevImportFilesDir(t *testing.T) {1342 assert := asrt.New(t)1343 app := &ddevapp.DdevApp{}1344 // Create a dummy directory to test non-archive imports1345 importDir, err := ioutil.TempDir("", t.Name())1346 assert.NoError(err)1347 fileNames := make([]string, 0)1348 for i := 0; i < 5; i++ {1349 fileName := uuid.New().String()1350 fileNames = append(fileNames, fileName)1351 fullPath := filepath.Join(importDir, fileName)1352 err = ioutil.WriteFile(fullPath, []byte(fileName), 0644)1353 assert.NoError(err)1354 }1355 for _, site := range TestSites {1356 if site.FilesTarballURL == "" && site.FilesZipballURL == "" {1357 t.Logf("=== SKIP TestDdevImportFilesDir for %s (FilesTarballURL and FilesZipballURL are not provided)\n", site.Name)1358 continue1359 }1360 switchDir := site.Chdir()1361 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s %s", site.Name, t.Name()))1362 t.Logf("=== BEGIN TestDdevImportFilesDir for %s\n", site.Name)1363 testcommon.ClearDockerEnv()1364 err = app.Init(site.Dir)1365 assert.NoError(err)1366 // Function under test1367 err = app.ImportFiles(importDir, "")1368 assert.NoError(err, "Importing a directory returned an error:", err)1369 // Confirm contents of destination dir after import1370 absUploadDir := filepath.Join(app.AppRoot, app.Docroot, app.GetUploadDir())1371 uploadedFiles, err := ioutil.ReadDir(absUploadDir)1372 assert.NoError(err)1373 uploadedFilesMap := map[string]bool{}1374 for _, uploadedFile := range uploadedFiles {1375 uploadedFilesMap[filepath.Base(uploadedFile.Name())] = true1376 }1377 for _, expectedFile := range fileNames {1378 assert.True(uploadedFilesMap[expectedFile], "Expected file %s not found for site: %s", expectedFile, site.Name)1379 }1380 runTime()1381 switchDir()1382 }1383}1384// TestDdevImportFiles tests the functionality that is called when "ddev import-files" is executed1385func TestDdevImportFiles(t *testing.T) {1386 assert := asrt.New(t)1387 app := &ddevapp.DdevApp{}1388 for _, site := range TestSites {1389 if site.FilesTarballURL == "" && site.FilesZipballURL == "" && site.FullSiteTarballURL == "" {1390 t.Logf("=== SKIP TestDdevImportFiles for %s (FilesTarballURL and FilesZipballURL are not provided)\n", site.Name)1391 continue1392 }1393 switchDir := site.Chdir()1394 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s %s", site.Name, t.Name()))1395 testcommon.ClearDockerEnv()1396 err := app.Init(site.Dir)1397 assert.NoError(err)1398 app.Hooks = map[string][]ddevapp.YAMLTask{"post-import-files": {{"exec-host": "touch hello-post-import-files-" + app.Name}}, "pre-import-files": {{"exec-host": "touch hello-pre-import-files-" + app.Name}}}1399 if site.FilesTarballURL != "" {1400 _, tarballPath, err := testcommon.GetCachedArchive(site.Name, "local-tarballs-files", "", site.FilesTarballURL)1401 assert.NoError(err)1402 err = app.ImportFiles(tarballPath, "")1403 assert.NoError(err)1404 }1405 if site.FilesZipballURL != "" {1406 _, zipballPath, err := testcommon.GetCachedArchive(site.Name, "local-zipballs-files", "", site.FilesZipballURL)1407 assert.NoError(err)1408 err = app.ImportFiles(zipballPath, "")1409 assert.NoError(err)1410 }1411 if site.FullSiteTarballURL != "" && site.FullSiteArchiveExtPath != "" {1412 _, siteTarPath, err := testcommon.GetCachedArchive(site.Name, "local-site-tar", "", site.FullSiteTarballURL)1413 assert.NoError(err)1414 err = app.ImportFiles(siteTarPath, site.FullSiteArchiveExtPath)1415 assert.NoError(err)1416 }1417 assert.FileExists("hello-pre-import-files-" + app.Name)1418 assert.FileExists("hello-post-import-files-" + app.Name)1419 err = os.Remove("hello-pre-import-files-" + app.Name)1420 assert.NoError(err)1421 err = os.Remove("hello-post-import-files-" + app.Name)1422 assert.NoError(err)1423 runTime()1424 switchDir()1425 }1426}1427// TestDdevImportFilesCustomUploadDir ensures that files are imported to a custom upload directory when requested1428func TestDdevImportFilesCustomUploadDir(t *testing.T) {1429 assert := asrt.New(t)1430 app := &ddevapp.DdevApp{}1431 for _, site := range TestSites {1432 switchDir := site.Chdir()1433 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s %s", site.Name, t.Name()))1434 t.Logf("=== BEGIN TestDdevImportFilesCustomUploadDir for %s\n", site.Name)1435 testcommon.ClearDockerEnv()1436 err := app.Init(site.Dir)1437 assert.NoError(err)1438 // Set custom upload dir1439 app.UploadDir = "my/upload/dir"1440 absUploadDir := filepath.Join(app.AppRoot, app.Docroot, app.UploadDir)1441 err = os.MkdirAll(absUploadDir, 0755)1442 assert.NoError(err)1443 if site.FilesTarballURL != "" {1444 _, tarballPath, err := testcommon.GetCachedArchive(site.Name, "local-tarballs-files", "", site.FilesTarballURL)1445 assert.NoError(err)1446 err = app.ImportFiles(tarballPath, "")1447 assert.NoError(err)1448 // Ensure upload dir isn't empty1449 fileInfoSlice, err := ioutil.ReadDir(absUploadDir)1450 assert.NoError(err)1451 assert.NotEmpty(fileInfoSlice)1452 }1453 if site.FilesZipballURL != "" {1454 _, zipballPath, err := testcommon.GetCachedArchive(site.Name, "local-zipballs-files", "", site.FilesZipballURL)1455 assert.NoError(err)1456 err = app.ImportFiles(zipballPath, "")1457 assert.NoError(err)1458 // Ensure upload dir isn't empty1459 fileInfoSlice, err := ioutil.ReadDir(absUploadDir)1460 assert.NoError(err)1461 assert.NotEmpty(fileInfoSlice)1462 }1463 if site.FullSiteTarballURL != "" && site.FullSiteArchiveExtPath != "" {1464 _, siteTarPath, err := testcommon.GetCachedArchive(site.Name, "local-site-tar", "", site.FullSiteTarballURL)1465 assert.NoError(err)1466 err = app.ImportFiles(siteTarPath, site.FullSiteArchiveExtPath)1467 assert.NoError(err)1468 // Ensure upload dir isn't empty1469 fileInfoSlice, err := ioutil.ReadDir(absUploadDir)1470 assert.NoError(err)1471 assert.NotEmpty(fileInfoSlice)1472 }1473 runTime()1474 switchDir()1475 }1476}1477// TestDdevExec tests the execution of commands inside a docker container of a site.1478func TestDdevExec(t *testing.T) {1479 assert := asrt.New(t)1480 app := &ddevapp.DdevApp{}1481 testDir, _ := os.Getwd()1482 for index, site := range TestSites {1483 switchDir := site.Chdir()1484 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s DdevExec", site.Name))1485 if index == 0 {1486 err := fileutil.CopyFile(filepath.Join(testDir, "testdata", t.Name(), "docker-compose.busybox.yaml"), filepath.Join(site.Dir, ".ddev", "docker-compose.busybox.yaml"))1487 defer func() {1488 err = os.RemoveAll(filepath.Join(site.Dir, ".ddev", "docker-compose.busybox.yaml"))1489 assert.NoError(err)1490 }()1491 assert.NoError(err)1492 }1493 err := app.Init(site.Dir)1494 assert.NoError(err)1495 app.Hooks = map[string][]ddevapp.YAMLTask{"post-exec": {{"exec-host": "touch hello-post-exec-" + app.Name}}, "pre-exec": {{"exec-host": "touch hello-pre-exec-" + app.Name}}}1496 defer func() {1497 app.Hooks = nil1498 _ = app.Stop(true, false)1499 _ = app.WriteConfig()1500 }()1501 startErr := app.Start()1502 if startErr != nil {1503 logs, err := ddevapp.GetErrLogsFromApp(app, startErr)1504 assert.NoError(err)1505 t.Fatalf("app.Start() failed err=%v, logs from broken container:\n=======\n%s\n========\n", startErr, logs)1506 }1507 out, _, err := app.Exec(&ddevapp.ExecOpts{1508 Service: "web",1509 Cmd: "pwd",1510 })1511 assert.NoError(err)1512 assert.Contains(out, "/var/www/html")1513 assert.FileExists("hello-pre-exec-" + app.Name)1514 assert.FileExists("hello-post-exec-" + app.Name)1515 err = os.Remove("hello-pre-exec-" + app.Name)1516 assert.NoError(err)1517 err = os.Remove("hello-post-exec-" + app.Name)1518 assert.NoError(err)1519 out, _, err = app.Exec(&ddevapp.ExecOpts{1520 Service: "web",1521 Dir: "/usr/local",1522 Cmd: "pwd",1523 })1524 assert.NoError(err)1525 assert.Contains(out, "/usr/local")1526 _, _, err = app.Exec(&ddevapp.ExecOpts{1527 Service: "db",1528 Cmd: "mysql -e 'DROP DATABASE db;'",1529 })1530 assert.NoError(err)1531 _, _, err = app.Exec(&ddevapp.ExecOpts{1532 Service: "db",1533 Cmd: "mysql information_schema -e 'CREATE DATABASE db;'",1534 })1535 assert.NoError(err)1536 switch app.GetType() {1537 case nodeps.AppTypeDrupal6:1538 fallthrough1539 case nodeps.AppTypeDrupal7:1540 fallthrough1541 case nodeps.AppTypeDrupal8:1542 out, _, err = app.Exec(&ddevapp.ExecOpts{1543 Service: "web",1544 Cmd: "drush status",1545 })1546 assert.NoError(err)1547 assert.Regexp("PHP configuration[ :]*/etc/php/[0-9].[0-9]/cli/php.ini", out)1548 case nodeps.AppTypeWordPress:1549 out, _, err = app.Exec(&ddevapp.ExecOpts{1550 Service: "web",1551 Cmd: "wp --info",1552 })1553 assert.NoError(err)1554 assert.Regexp("/etc/php.*/php.ini", out)1555 // Make sure error works for unset env vars, etc.1556 _, stderr, err := app.Exec(&ddevapp.ExecOpts{1557 Service: "web",1558 Cmd: "echo $ENVDOESNOTEXIST",1559 })1560 assert.Error(err)1561 assert.Contains(stderr, "ENVDOESNOTEXIST: unbound variable")1562 }1563 // Make sure that exec works on non-ddev container like busybox as well1564 if index == 0 {1565 _, _, err = app.Exec(&ddevapp.ExecOpts{1566 Service: "busybox",1567 Cmd: "ls | grep bin",1568 })1569 assert.NoError(err)1570 _, stderr, err := app.Exec(&ddevapp.ExecOpts{1571 Service: "busybox",1572 Cmd: "echo $ENVDOESNOTEXIST",1573 })1574 assert.Error(err)1575 assert.Contains(stderr, "parameter not set")1576 _, stderr, err = app.Exec(&ddevapp.ExecOpts{1577 Service: "busybox",1578 Cmd: "this is an error;",1579 })1580 assert.Error(err)1581 assert.Contains(stderr, "this: not found")1582 }1583 err = app.Stop(true, false)1584 assert.NoError(err)1585 runTime()1586 switchDir()1587 }1588}1589// TestDdevLogs tests the container log output functionality.1590func TestDdevLogs(t *testing.T) {1591 assert := asrt.New(t)1592 // Skip test because on Windows because the CaptureUserOut() hangs, at least1593 // sometimes.1594 if runtime.GOOS == "windows" {1595 t.Skip("Skipping test TestDdevLogs on Windows")1596 }1597 app := &ddevapp.DdevApp{}1598 site := TestSites[0]1599 switchDir := site.Chdir()1600 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s DdevLogs", site.Name))1601 err := app.Init(site.Dir)1602 assert.NoError(err)1603 //nolint: errcheck1604 defer app.Stop(true, false)1605 startErr := app.StartAndWait(0)1606 if startErr != nil {1607 logs, err := ddevapp.GetErrLogsFromApp(app, startErr)1608 assert.NoError(err)1609 t.Fatalf("app.Start failed, err=%v, logs=\n========\n%s\n===========\n", startErr, logs)1610 }1611 out, err := app.CaptureLogs("web", false, "")1612 assert.NoError(err)1613 assert.Contains(out, "Server started")1614 out, err = app.CaptureLogs("db", false, "")1615 assert.NoError(err)1616 assert.Contains(out, "MySQL init process done. Ready for start up.")1617 // Test that we can get logs when project is stopped also1618 err = app.Pause()1619 assert.NoError(err)1620 out, err = app.CaptureLogs("web", false, "")1621 assert.NoError(err)1622 assert.Contains(out, "Server started")1623 out, err = app.CaptureLogs("db", false, "")1624 assert.NoError(err)1625 assert.Contains(out, "MySQL init process done. Ready for start up.")1626 runTime()1627 switchDir()1628}1629// TestProcessHooks tests execution of commands defined in config.yaml1630func TestProcessHooks(t *testing.T) {1631 assert := asrt.New(t)1632 site := TestSites[0]1633 switchDir := site.Chdir()1634 runTime := util.TimeTrack(time.Now(), t.Name())1635 testcommon.ClearDockerEnv()1636 app, err := ddevapp.NewApp(site.Dir, true, nodeps.ProviderDefault)1637 assert.NoError(err)1638 defer func() {1639 _ = app.Stop(true, false)1640 app.Hooks = nil1641 _ = app.WriteConfig()1642 switchDir()1643 }()1644 err = app.Start()1645 assert.NoError(err)1646 // Note that any ExecHost commands must be able to run on Windows.1647 // echo and pwd are things that work pretty much the same in both places.1648 app.Hooks = map[string][]ddevapp.YAMLTask{1649 "hook-test": {1650 {"exec": "ls /usr/local/bin/composer"},1651 {"exec-host": "echo something"},1652 {"exec": "echo MYSQL_USER=${MYSQL_USER}", "service": "db"},1653 {"exec": "echo TestProcessHooks > /var/www/html/TestProcessHooks${DDEV_ROUTER_HTTPS_PORT}.txt"},1654 {"exec": "touch /var/tmp/TestProcessHooks && touch /var/www/html/touch_works_after_and.txt"},1655 },1656 }1657 captureOutputFunc, err := util.CaptureOutputToFile()1658 assert.NoError(err)1659 userOutFunc := util.CaptureUserOut()1660 err = app.ProcessHooks("hook-test")1661 assert.NoError(err)1662 out := captureOutputFunc()1663 userOut := userOutFunc()1664 // Ignore color in output, can be different in different OS's1665 out = vtclean.Clean(out, false)1666 assert.Contains(userOut, "Executing hook-test hook")1667 assert.Contains(userOut, "Exec command 'ls /usr/local/bin/composer' in container/service 'web'")1668 assert.Contains(userOut, "Exec command 'echo something' on the host")1669 assert.Contains(userOut, "Exec command 'echo MYSQL_USER=${MYSQL_USER}' in container/service 'db'")1670 assert.Contains(out, "MYSQL_USER=db")1671 assert.Contains(userOut, "Exec command 'echo TestProcessHooks > /var/www/html/TestProcessHooks${DDEV_ROUTER_HTTPS_PORT}.txt' in container/service 'web'")1672 assert.Contains(userOut, "Exec command 'touch /var/tmp/TestProcessHooks && touch /var/www/html/touch_works_after_and.txt' in container/service 'web',")1673 assert.FileExists(filepath.Join(app.AppRoot, fmt.Sprintf("TestProcessHooks%s.txt", app.RouterHTTPSPort)))1674 assert.FileExists(filepath.Join(app.AppRoot, "touch_works_after_and.txt"))1675 err = app.Stop(true, false)1676 assert.NoError(err)1677 runTime()1678}1679// TestDdevPause tests the functionality that is called when "ddev pause" is executed1680func TestDdevPause(t *testing.T) {1681 assert := asrt.New(t)1682 app := &ddevapp.DdevApp{}1683 site := TestSites[0]1684 switchDir := site.Chdir()1685 runTime := util.TimeTrack(time.Now(), fmt.Sprintf("%s DdevStop", site.Name))1686 testcommon.ClearDockerEnv()1687 err := app.Init(site.Dir)1688 assert.NoError(err)1689 err = app.StartAndWait(0)1690 app.Hooks = map[string][]ddevapp.YAMLTask{"post-pause": {{"exec-host": "touch hello-post-pause-" + app.Name}}, "pre-pause": {{"exec-host": "touch hello-pre-pause-" + app.Name}}}1691 defer func() {1692 app.Hooks = nil1693 _ = app.WriteConfig()1694 _ = app.Stop(true, false)1695 }()1696 require.NoError(t, err)1697 err = app.Pause()1698 assert.NoError(err)1699 for _, containerType := range [3]string{"web", "db", "dba"} {1700 containerName, err := constructContainerName(containerType, app)1701 assert.NoError(err)1702 check, err := testcommon.ContainerCheck(containerName, "exited")1703 assert.NoError(err)1704 assert.True(check, containerType, "container has exited")1705 }1706 assert.FileExists("hello-pre-pause-" + app.Name)1707 assert.FileExists("hello-post-pause-" + app.Name)1708 err = os.Remove("hello-pre-pause-" + app.Name)1709 assert.NoError(err)1710 err = os.Remove("hello-post-pause-" + app.Name)1711 assert.NoError(err)1712 runTime()1713 switchDir()1714}1715// TestDdevStopMissingDirectory tests that the 'ddev stop' command works properly on sites with missing directories or ddev configs.1716func TestDdevStopMissingDirectory(t *testing.T) {1717 if runtime.GOOS == "windows" {1718 t.Skip("Skipping because unreliable on Windows")1719 }1720 assert := asrt.New(t)1721 site := TestSites[0]1722 testcommon.ClearDockerEnv()1723 app := &ddevapp.DdevApp{}1724 err := app.Init(site.Dir)1725 assert.NoError(err)1726 startErr := app.StartAndWait(0)1727 //nolint: errcheck1728 defer app.Stop(true, false)1729 if startErr != nil {1730 logs, err := ddevapp.GetErrLogsFromApp(app, startErr)1731 assert.NoError(err)1732 t.Fatalf("app.StartAndWait failed err=%v logs from broken container: \n=======\n%s\n========\n", startErr, logs)1733 }1734 tempPath := testcommon.CreateTmpDir("site-copy")1735 siteCopyDest := filepath.Join(tempPath, "site")1736 defer removeAllErrCheck(tempPath, assert)1737 _ = app.Stop(false, false)1738 // Move the site directory to a temp location to mimic a missing directory.1739 err = os.Rename(site.Dir, siteCopyDest)1740 assert.NoError(err)1741 //nolint: errcheck1742 defer os.Rename(siteCopyDest, site.Dir)1743 // ddev stop (in cmd) actually does the check for missing project files,1744 // so we imitate that here.1745 err = ddevapp.CheckForMissingProjectFiles(app)1746 assert.Error(err)1747 if err != nil {1748 assert.Contains(err.Error(), "If you would like to continue using ddev to manage this project please restore your files to that directory.")1749 }1750}1751// TestDdevDescribe tests that the describe command works properly on a running1752// and also a stopped project.1753func TestDdevDescribe(t *testing.T) {1754 assert := asrt.New(t)1755 app := &ddevapp.DdevApp{}1756 site := TestSites[0]1757 switchDir := site.Chdir()1758 testcommon.ClearDockerEnv()1759 err := app.Init(site.Dir)1760 assert.NoError(err)1761 app.Hooks = map[string][]ddevapp.YAMLTask{"post-describe": {{"exec-host": "touch hello-post-describe-" + app.Name}}, "pre-describe": {{"exec-host": "touch hello-pre-describe-" + app.Name}}}1762 startErr := app.StartAndWait(0)1763 defer func() {1764 _ = app.Stop(true, false)1765 app.Hooks = nil1766 _ = app.WriteConfig()1767 }()1768 // If we have a problem starting, get the container logs and output.1769 if startErr != nil {1770 out, logsErr := app.CaptureLogs("web", false, "")1771 assert.NoError(logsErr)1772 healthcheck, inspectErr := exec.RunCommandPipe("sh", []string{"-c", fmt.Sprintf("docker inspect ddev-%s-web|jq -r '.[0].State.Health.Log[-1]'", app.Name)})1773 assert.NoError(inspectErr)1774 t.Fatalf("app.StartAndWait(%s) failed: %v, \nweb container healthcheck='%s', \n=== web container logs=\n%s\n=== END web container logs ===", site.Name, err, healthcheck, out)1775 }1776 desc, err := app.Describe(false)1777 assert.NoError(err)1778 assert.EqualValues(ddevapp.SiteRunning, desc["status"], "")1779 assert.EqualValues(app.GetName(), desc["name"])1780 assert.EqualValues(ddevapp.RenderHomeRootedDir(app.GetAppRoot()), desc["shortroot"])1781 assert.EqualValues(app.GetAppRoot(), desc["approot"])1782 assert.EqualValues(app.GetPhpVersion(), desc["php_version"])1783 assert.FileExists("hello-pre-describe-" + app.Name)1784 assert.FileExists("hello-post-describe-" + app.Name)1785 err = os.Remove("hello-pre-describe-" + app.Name)1786 assert.NoError(err)1787 err = os.Remove("hello-post-describe-" + app.Name)1788 assert.NoError(err)1789 // Now stop it and test behavior.1790 err = app.Pause()1791 assert.NoError(err)1792 desc, err = app.Describe(false)1793 assert.NoError(err)1794 assert.EqualValues(ddevapp.SitePaused, desc["status"])1795 switchDir()1796}1797// TestDdevDescribeMissingDirectory tests that the describe command works properly on sites with missing directories or ddev configs.1798func TestDdevDescribeMissingDirectory(t *testing.T) {1799 if runtime.GOOS == "windows" {1800 t.Skip("Skipping because unreliable on Windows")1801 }1802 assert := asrt.New(t)1803 site := TestSites[0]1804 tempPath := testcommon.CreateTmpDir("site-copy")1805 siteCopyDest := filepath.Join(tempPath, "site")1806 defer removeAllErrCheck(tempPath, assert)1807 app := &ddevapp.DdevApp{}1808 err := app.Init(site.Dir)1809 assert.NoError(err)1810 startErr := app.StartAndWait(0)1811 //nolint: errcheck1812 defer app.Stop(true, false)1813 if startErr != nil {1814 logs, err := ddevapp.GetErrLogsFromApp(app, startErr)1815 assert.NoError(err)1816 t.Fatalf("app.StartAndWait failed err=%v logs from broken container: \n=======\n%s\n========\n", startErr, logs)1817 }1818 // Move the site directory to a temp location to mimic a missing directory.1819 err = app.Stop(false, false)1820 assert.NoError(err)1821 err = os.Rename(site.Dir, siteCopyDest)1822 assert.NoError(err)1823 desc, err := app.Describe(false)1824 assert.NoError(err)1825 assert.Contains(desc["status"], ddevapp.SiteDirMissing, "Status did not include the phrase '%s' when describing a site with missing directories.", ddevapp.SiteDirMissing)1826 // Move the site directory back to its original location.1827 err = os.Rename(siteCopyDest, site.Dir)1828 assert.NoError(err)1829}1830// TestRouterPortsCheck makes sure that we can detect if the ports are available before starting the router.1831func TestRouterPortsCheck(t *testing.T) {1832 assert := asrt.New(t)1833 // First, stop any sites that might be running1834 app := &ddevapp.DdevApp{}1835 // Stop/Remove all sites, which should get the router out of there.1836 for _, site := range TestSites {1837 switchDir := site.Chdir()1838 testcommon.ClearDockerEnv()1839 err := app.Init(site.Dir)1840 assert.NoError(err)1841 if app.SiteStatus() == ddevapp.SiteRunning || app.SiteStatus() == ddevapp.SitePaused {1842 err = app.Stop(true, false)1843 assert.NoError(err)1844 }1845 switchDir()1846 }1847 // Now start one site, it's hard to get router to behave without one site.1848 site := TestSites[0]1849 testcommon.ClearDockerEnv()1850 err := app.Init(site.Dir)1851 assert.NoError(err)1852 startErr := app.StartAndWait(5)1853 //nolint: errcheck1854 defer app.Stop(true, false)1855 if startErr != nil {1856 appLogs, getLogsErr := ddevapp.GetErrLogsFromApp(app, startErr)1857 assert.NoError(getLogsErr)1858 t.Fatalf("app.StartAndWait() failure; err=%v logs:\n=====\n%s\n=====\n", startErr, appLogs)1859 }1860 app, err = ddevapp.GetActiveApp(site.Name)1861 if err != nil {1862 t.Fatalf("Failed to GetActiveApp(%s), err:%v", site.Name, err)1863 }1864 startErr = app.StartAndWait(5)1865 //nolint: errcheck1866 defer app.Stop(true, false)1867 if startErr != nil {1868 appLogs, getLogsErr := ddevapp.GetErrLogsFromApp(app, startErr)1869 assert.NoError(getLogsErr)1870 t.Fatalf("app.StartAndWait() failure err=%v logs:\n=====\n%s\n=====\n", startErr, appLogs)1871 }1872 // Stop the router using code from StopRouterIfNoContainers().1873 // StopRouterIfNoContainers can't be used here because it checks to see if containers are running1874 // and doesn't do its job as a result.1875 dest := ddevapp.RouterComposeYAMLPath()1876 _, _, err = dockerutil.ComposeCmd([]string{dest}, "-p", ddevapp.RouterProjectName, "down")1877 assert.NoError(err, "Failed to stop router using docker-compose, err=%v", err)1878 // Occupy port 80 using docker busybox trick, then see if we can start router.1879 // This is done with docker so that we don't have to use explicit sudo1880 containerID, err := exec.RunCommand("sh", []string{"-c", "docker run -d -p80:80 --rm busybox:latest sleep 100 2>/dev/null"})1881 if err != nil {1882 t.Fatalf("Failed to run docker command to occupy port 80, err=%v output=%v", err, containerID)1883 }1884 containerID = strings.TrimSpace(containerID)1885 // Now try to start the router. It should fail because the port is occupied.1886 err = ddevapp.StartDdevRouter()1887 assert.Error(err, "Failure: router started even though port 80 was occupied")1888 // Remove our dummy busybox docker container.1889 out, err := exec.RunCommand("docker", []string{"rm", "-f", containerID})1890 assert.NoError(err, "Failed to docker rm the port-occupier container, err=%v output=%v", err, out)1891}1892// TestCleanupWithoutCompose ensures app containers can be properly cleaned up without a docker-compose config file present.1893func TestCleanupWithoutCompose(t *testing.T) {1894 assert := asrt.New(t)1895 // Skip test because we can't rename folders while they're in use if running on Windows.1896 if runtime.GOOS == "windows" {1897 t.Skip("Skipping test TestCleanupWithoutCompose on Windows")1898 }1899 site := TestSites[0]1900 revertDir := site.Chdir()1901 app := &ddevapp.DdevApp{}1902 testcommon.ClearDockerEnv()1903 err := app.Init(site.Dir)1904 assert.NoError(err)1905 // Ensure we have a site started so we have something to cleanup1906 startErr := app.StartAndWait(5)1907 //nolint: errcheck1908 defer app.Stop(true, false)1909 if startErr != nil {1910 appLogs, getLogsErr := ddevapp.GetErrLogsFromApp(app, startErr)1911 assert.NoError(getLogsErr)1912 t.Fatalf("app.StartAndWait failure; err=%v, logs:\n=====\n%s\n=====\n", startErr, appLogs)1913 }1914 // Setup by creating temp directory and nesting a folder for our site.1915 tempPath := testcommon.CreateTmpDir("site-copy")1916 siteCopyDest := filepath.Join(tempPath, "site")1917 //nolint: errcheck1918 defer os.RemoveAll(tempPath)1919 //nolint: errcheck1920 defer revertDir()1921 // Move the site directory back to its original location.1922 //nolint: errcheck1923 defer os.Rename(siteCopyDest, site.Dir)1924 // Move site directory to a temp directory to mimick a missing directory.1925 err = os.Rename(site.Dir, siteCopyDest)1926 assert.NoError(err)1927 // Call the Stop command()1928 // Notice that we set the removeData parameter to true.1929 // This gives us added test coverage over sites with missing directories1930 // by ensuring any associated database files get cleaned up as well.1931 err = app.Stop(true, false)1932 assert.NoError(err)1933 assert.Empty(globalconfig.DdevGlobalConfig.ProjectList[app.Name])1934 for _, containerType := range [3]string{"web", "db", "dba"} {1935 _, err := constructContainerName(containerType, app)1936 assert.Error(err)1937 }1938 // Ensure there are no volumes associated with this project1939 client := dockerutil.GetDockerClient()1940 volumes, err := client.ListVolumes(docker.ListVolumesOptions{})1941 assert.NoError(err)1942 for _, volume := range volumes {1943 assert.False(volume.Labels["com.docker.compose.project"] == "ddev"+strings.ToLower(app.GetName()))1944 }1945}1946// TestGetappsEmpty ensures that GetActiveProjects returns an empty list when no applications are running.1947func TestGetAppsEmpty(t *testing.T) {1948 assert := asrt.New(t)1949 // Ensure test sites are removed1950 for _, site := range TestSites {1951 app := &ddevapp.DdevApp{}1952 switchDir := site.Chdir()1953 testcommon.ClearDockerEnv()1954 err := app.Init(site.Dir)1955 assert.NoError(err)1956 if app.SiteStatus() != ddevapp.SiteStopped {1957 err = app.Stop(true, false)1958 assert.NoError(err)1959 }1960 switchDir()1961 }1962 apps := ddevapp.GetActiveProjects()1963 assert.Equal(0, len(apps), "Expected to find no apps but found %d apps=%v", len(apps), apps)1964}1965// TestRouterNotRunning ensures the router is shut down after all sites are stopped.1966// This depends on TestGetAppsEmpty() having shut everything down.1967func TestRouterNotRunning(t *testing.T) {1968 assert := asrt.New(t)1969 containers, err := dockerutil.GetDockerContainers(false)1970 assert.NoError(err)1971 for _, container := range containers {1972 assert.NotEqual("ddev-router", dockerutil.ContainerName(container), "ddev-router was not supposed to be running but it was")1973 }1974}1975// TestListWithoutDir prevents regression where ddev list panics if one of the1976// sites found is missing a directory1977func TestListWithoutDir(t *testing.T) {1978 if runtime.GOOS == "windows" {1979 t.Skip("Skipping because unreliable on Windows")1980 }...

Full Screen

Full Screen

regression.go

Source:regression.go Github

copy

Full Screen

...78 }79 r.tele.DeleteTc(r.client, ctx)80 return nil81}82func (r *Regression) GetApps(ctx context.Context, cid string) ([]string, error) {83 apps, err := r.tdb.GetApps(ctx, cid)84 if apps != nil && len(apps) != r.appCount {85 r.tele.GetApps(len(apps), r.client, ctx)86 r.appCount = len(apps)87 }88 return apps, err89}90// sanitiseInput sanitises user input strings before logging them for safety, removing newlines91// and escaping HTML tags. This is to prevent log injection, including forgery of log records.92// Reference: https://www.owasp.org/index.php/Log_Injection93func sanitiseInput(s string) string {94 re := regexp.MustCompile(`(\n|\n\r|\r\n|\r)`)95 return html.EscapeString(string(re.ReplaceAll([]byte(s), []byte(""))))96}97func (r *Regression) Get(ctx context.Context, cid, appID, id string) (models.TestCase, error) {98 tcs, err := r.tdb.Get(ctx, cid, id)99 if err != nil {...

Full Screen

Full Screen

service.go

Source:service.go Github

copy

Full Screen

...9 GetAll(ctx context.Context, cid, appID string, offset *int, limit *int) ([]models.TestCase, error)10 Put(ctx context.Context, cid string, t []models.TestCase) ([]string, error)11 DeNoise(ctx context.Context, cid, id, app, body string, h http.Header) error12 Test(ctx context.Context, cid, app, runID, id string, resp models.HttpResp) (bool, error)13 GetApps(ctx context.Context, cid string) ([]string, error)14 UpdateTC(ctx context.Context, t []models.TestCase) error15 DeleteTC(ctx context.Context, cid, id string) error16}...

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 apps := regression.GetApps()4 fmt.Println(apps)5}6import (7func main() {8 apps := regression.GetApps()9 fmt.Println(apps)10}11import (12func main() {13 apps := regression.GetApps()14 fmt.Println(apps)15}16import (17func main() {18 apps := regression.GetApps()19 fmt.Println(apps)20}21import (22func main() {23 apps := regression.GetApps()24 fmt.Println(apps)25}26import (27func main() {28 apps := regression.GetApps()29 fmt.Println(apps)30}31import (32func main() {33 apps := regression.GetApps()34 fmt.Println(apps)35}36import (37func main() {38 apps := regression.GetApps()39 fmt.Println(apps)40}41import (42func main() {43 apps := regression.GetApps()44 fmt.Println(apps)45}46import (47func main() {48 apps := regression.GetApps()49 fmt.Println(apps)50}

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 r := regression.New()4 r.Train(regression.Data{5 X: []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},6 Y: []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},7 })8 r.Run()9 fmt.Println(r.GetApps())10}11import (12func main() {13 r := regression.New()14 r.Train(regression.Data{15 X: []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},16 Y: []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},17 })18 r.Run()19 fmt.Println(r.GetFormula())20}21import (22func main() {23 r := regression.New()24 r.Train(regression.Data{25 X: []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},26 Y: []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},27 })28 r.Run()29 fmt.Println(r.GetFormula())30 fmt.Println(r.GetApps())31}32import (33func main() {34 r := regression.New()35 r.Train(regression.Data{36 X: []float64{0, 1, 2, 3, 4, 5, 6,

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 r := regression.New()4 apps, err := r.GetApps()5 if err != nil {6 fmt.Println(err)7 }8 for _, app := range apps {9 fmt.Println(app.AppName)10 }11}

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 r := regression.New()4 r.Train(regression.DataPoint(0.0, 0.0))5 r.Train(regression.DataPoint(1.0, 1.0))6 r.Train(regression.DataPoint(2.0, 2.0))7 r.Train(regression.DataPoint(3.0, 3.0))8 r.Train(regression.DataPoint(4.0, 4.0))9 r.Train(regression.DataPoint(5.0, 5.0))10 r.Train(regression.DataPoint(6.0, 6.0))11 r.Train(regression.DataPoint(7.0, 7.0))12 r.Train(regression.DataPoint(8.0, 8.0))13 r.Train(regression.DataPoint(9.0, 9.0))14 r.Run()15 fmt.Printf("Regression equation: %s16 fmt.Printf("Coefficient of determination: %0.2f17", r.GetCoefficientOfDetermination())18 fmt.Printf("Predicted value for x = 5.0: %0.2f19", r.Predict(5.0))20 fmt.Printf("Predicted value for x = 10.0: %0.2f21", r.Predict(10.0))22 fmt.Printf("Predicted value for x = 15.0: %0.2f23", r.Predict(15.0))24 fmt.Printf("Predicted value for x = 20.0: %0.2f25", r.Predict(20.0))26 fmt.Printf("Predicted value for x = 25.0: %0.2f27", r.Predict(25.0))28 fmt.Printf("Predicted value

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 reg := regression.Regression{}4 apps := reg.GetApps()5 table := tablewriter.NewWriter(os.Stdout)6 table.SetHeader([]string{"App Name", "App Id"})7 for _, app := range apps {8 table.Append([]string{app.Name, app.Id})9 }10 table.Render()11}

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 reg := regression.Regression{}4 result, err := reg.GetApps()5 if err != nil {6 fmt.Println("Error:", err)7 } else {8 fmt.Println("Result:", result)9 }10}11import (12func main() {13 reg := regression.Regression{}14 result, err := reg.GetApps()15 if err != nil {16 fmt.Println("Error:", err)17 } else {18 fmt.Println("Result:", result)19 }20}21import (22func main() {23 reg := regression.Regression{}24 result, err := reg.GetApps()25 if err != nil {26 fmt.Println("Error:", err)27 } else {28 fmt.Println("Result:", result)29 }30}

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println("Hello World!")4 apps = obj.GetApps()5 fmt.Println(apps)6}

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 obj := new(regression.Regression)4 apps := obj.GetApps()5 fmt.Println(apps)6}7import (8func main() {9 obj := regression.Regression{}10 apps := obj.GetApps()11 fmt.Println(apps)12}13import (14func main() {15 obj := regression.Regression{Apps: []string{"App1", "App2", "App3"}}16 apps := obj.GetApps()17 fmt.Println(apps)18}

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 apps, err := r.GetApps()4 if err != nil {5 fmt.Println(err)6 }7 fmt.Println(apps)8}9import (10func main() {11 apps, err := r.GetApps()12 if err != nil {13 fmt.Println(err)14 }15 fmt.Println(apps)16}17import (18func main() {19 apps, err := r.GetApps()20 if err != nil {21 fmt.Println(err)22 }23 fmt.Println(apps)24}25import (26func main() {27 apps, err := r.GetApps()28 if err != nil {29 fmt.Println(err)30 }31 fmt.Println(apps)32}33import (34func main() {35 apps, err := r.GetApps()36 if err != nil {37 fmt.Println(err)38 }39 fmt.Println(apps)40}41import (42func main() {43 apps, err := r.GetApps()

Full Screen

Full Screen

GetApps

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 reg := regression.NewRegression()4 apps := reg.GetApps()5 fmt.Println(apps)6}7[{"id":1,"name":"App1","description":"This is app 1"},{"id":2,"name":"App2","description":"This is app 2"},{"id":3,"name":"App3","description":"This is app 3"}]

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Keploy automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful