2021-01-06 17:25:50 +03:00
|
|
|
/*
|
|
|
|
Copyright 2021 The Vitess Authors.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
2021-08-30 09:00:03 +03:00
|
|
|
"path"
|
2021-01-06 17:25:50 +03:00
|
|
|
"strings"
|
|
|
|
"text/template"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
workflowConfigDir = "../.github/workflows"
|
|
|
|
|
|
|
|
unitTestTemplate = "templates/unit_test.tpl"
|
2021-11-12 18:21:36 +03:00
|
|
|
unitTestDatabases = "mysql57, mariadb103, mysql80, mariadb102"
|
2021-01-06 17:25:50 +03:00
|
|
|
|
2021-12-14 05:50:50 +03:00
|
|
|
// An empty string will cause the default non platform specific template
|
|
|
|
// to be used.
|
|
|
|
clusterTestTemplateFormatStr = "templates/cluster_endtoend_test%s.tpl"
|
2021-08-30 09:00:03 +03:00
|
|
|
|
|
|
|
unitTestSelfHostedTemplate = "templates/unit_test_self_hosted.tpl"
|
2021-11-12 18:21:36 +03:00
|
|
|
unitTestSelfHostedDatabases = ""
|
2021-08-30 09:00:03 +03:00
|
|
|
dockerFileTemplate = "templates/dockerfile.tpl"
|
|
|
|
clusterTestSelfHostedTemplate = "templates/cluster_endtoend_test_self_hosted.tpl"
|
2021-12-14 23:26:20 +03:00
|
|
|
clusterTestDockerTemplate = "templates/cluster_endtoend_test_docker.tpl"
|
2021-03-02 12:56:44 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2021-10-07 09:31:38 +03:00
|
|
|
// Clusters 10, 25 are executed on docker, using the docker_test_cluster 10, 25 workflows.
|
|
|
|
// Hence, they are not listed in the list below.
|
2021-03-02 12:56:44 +03:00
|
|
|
clusterList = []string{
|
2022-03-24 02:11:36 +03:00
|
|
|
"vtctlbackup_sharded_clustertest_heavy",
|
2021-03-02 12:56:44 +03:00
|
|
|
"13",
|
2022-03-24 02:11:36 +03:00
|
|
|
"ers_prs_newfeatures_heavy",
|
2021-03-02 12:56:44 +03:00
|
|
|
"15",
|
2022-03-24 02:11:36 +03:00
|
|
|
"shardedrecovery_stress_verticalsplit_heavy",
|
2021-10-04 16:22:12 +03:00
|
|
|
"17",
|
2021-03-02 12:56:44 +03:00
|
|
|
"19",
|
|
|
|
"20",
|
|
|
|
"21",
|
|
|
|
"22",
|
2022-03-24 02:11:36 +03:00
|
|
|
"worker_vault_heavy",
|
2021-03-02 12:56:44 +03:00
|
|
|
"24",
|
2021-10-07 09:31:38 +03:00
|
|
|
"26",
|
2021-07-10 15:02:04 +03:00
|
|
|
"vstream_failover",
|
2021-08-15 00:14:05 +03:00
|
|
|
"vstream_stoponreshard_true",
|
|
|
|
"vstream_stoponreshard_false",
|
2021-10-13 09:00:55 +03:00
|
|
|
"vstream_with_keyspaces_to_watch",
|
2021-03-02 12:56:44 +03:00
|
|
|
"onlineddl_ghost",
|
|
|
|
"onlineddl_vrepl",
|
|
|
|
"onlineddl_vrepl_stress",
|
2021-06-24 11:41:17 +03:00
|
|
|
"onlineddl_vrepl_stress_suite",
|
2021-05-25 10:57:20 +03:00
|
|
|
"onlineddl_vrepl_suite",
|
2021-03-03 08:18:21 +03:00
|
|
|
"vreplication_migrate",
|
2021-03-07 10:39:46 +03:00
|
|
|
"onlineddl_revert",
|
2021-03-18 14:42:54 +03:00
|
|
|
"onlineddl_declarative",
|
2021-04-22 14:58:26 +03:00
|
|
|
"onlineddl_singleton",
|
2021-11-14 22:18:34 +03:00
|
|
|
"onlineddl_scheduler",
|
2021-11-18 13:45:36 +03:00
|
|
|
"onlineddl_revertible",
|
2021-03-07 13:04:25 +03:00
|
|
|
"tabletmanager_throttler",
|
|
|
|
"tabletmanager_throttler_custom_config",
|
2021-04-25 13:31:48 +03:00
|
|
|
"tabletmanager_tablegc",
|
2021-10-04 17:44:22 +03:00
|
|
|
"tabletmanager_consul",
|
2021-06-10 13:40:57 +03:00
|
|
|
"vtgate_buffer",
|
|
|
|
"vtgate_concurrentdml",
|
2021-10-29 13:25:13 +03:00
|
|
|
"vtgate_godriver",
|
2021-06-10 17:44:59 +03:00
|
|
|
"vtgate_gen4",
|
|
|
|
"vtgate_readafterwrite",
|
2021-06-10 13:40:57 +03:00
|
|
|
"vtgate_reservedconn",
|
2021-06-10 17:44:59 +03:00
|
|
|
"vtgate_schema",
|
2022-03-23 03:33:10 +03:00
|
|
|
"vtgate_tablet_healthcheck_cache",
|
2021-06-10 17:44:59 +03:00
|
|
|
"vtgate_topo",
|
2021-10-04 17:44:22 +03:00
|
|
|
"vtgate_topo_consul",
|
|
|
|
"vtgate_topo_etcd",
|
2021-06-10 13:40:57 +03:00
|
|
|
"vtgate_transaction",
|
|
|
|
"vtgate_unsharded",
|
2021-06-10 17:44:59 +03:00
|
|
|
"vtgate_vindex",
|
2021-06-10 13:40:57 +03:00
|
|
|
"vtgate_vschema",
|
2021-10-04 16:22:12 +03:00
|
|
|
"vtgate_queries",
|
|
|
|
"vtgate_schema_tracker",
|
2021-06-10 13:40:57 +03:00
|
|
|
"xb_recovery",
|
2021-06-10 17:24:39 +03:00
|
|
|
"resharding",
|
|
|
|
"resharding_bytes",
|
2021-07-14 09:37:33 +03:00
|
|
|
"mysql80",
|
2022-02-14 19:45:44 +03:00
|
|
|
"vreplication_across_db_versions",
|
2021-08-30 09:00:03 +03:00
|
|
|
"vreplication_multicell",
|
|
|
|
"vreplication_cellalias",
|
2022-03-23 21:42:07 +03:00
|
|
|
"vreplication_basic",
|
|
|
|
"vreplication_v2",
|
2022-01-22 15:16:36 +03:00
|
|
|
"vtorc",
|
2022-03-28 19:37:13 +03:00
|
|
|
"vtorc_8.0",
|
2022-02-15 15:59:36 +03:00
|
|
|
"schemadiff_vrepl",
|
2021-08-30 09:00:03 +03:00
|
|
|
}
|
2021-11-12 18:21:36 +03:00
|
|
|
|
2022-04-06 19:09:26 +03:00
|
|
|
clusterSelfHostedList = []string{
|
|
|
|
"12",
|
|
|
|
"18",
|
|
|
|
}
|
2022-05-03 23:44:54 +03:00
|
|
|
clusterDockerList = []string{}
|
|
|
|
clustersRequiringXtraBackup = []string{
|
|
|
|
"20",
|
|
|
|
"xb_recovery",
|
|
|
|
}
|
|
|
|
clustersRequiringMakeTools = []string{
|
2021-03-02 12:56:44 +03:00
|
|
|
"18",
|
|
|
|
"24",
|
2021-10-04 17:44:22 +03:00
|
|
|
"vtgate_topo_consul",
|
|
|
|
"tabletmanager_consul",
|
2021-03-02 12:56:44 +03:00
|
|
|
}
|
2021-08-30 09:00:03 +03:00
|
|
|
clustersRequiringMySQL80 = []string{
|
2021-07-14 09:37:33 +03:00
|
|
|
"mysql80",
|
2022-03-28 19:37:13 +03:00
|
|
|
"vtorc_8.0",
|
2022-02-14 19:45:44 +03:00
|
|
|
"vreplication_across_db_versions",
|
2021-07-14 09:37:33 +03:00
|
|
|
}
|
2021-01-06 17:25:50 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
type unitTest struct {
|
2021-02-05 23:05:29 +03:00
|
|
|
Name, Platform string
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
type clusterTest struct {
|
2021-12-14 05:50:50 +03:00
|
|
|
Name, Shard, Platform string
|
2021-01-06 17:25:50 +03:00
|
|
|
MakeTools, InstallXtraBackup bool
|
2022-03-23 21:42:07 +03:00
|
|
|
Ubuntu20, Docker bool
|
|
|
|
LimitResourceUsage bool
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
|
2021-08-30 09:00:03 +03:00
|
|
|
type selfHostedTest struct {
|
|
|
|
Name, Platform, Dockerfile, Shard, ImageName, directoryName string
|
2022-03-23 21:42:07 +03:00
|
|
|
MakeTools, InstallXtraBackup, Docker bool
|
2021-08-30 09:00:03 +03:00
|
|
|
}
|
|
|
|
|
2021-01-06 17:25:50 +03:00
|
|
|
func mergeBlankLines(buf *bytes.Buffer) string {
|
|
|
|
var out []string
|
|
|
|
in := strings.Split(buf.String(), "\n")
|
|
|
|
lastWasBlank := false
|
|
|
|
for _, line := range in {
|
|
|
|
if strings.TrimSpace(line) == "" {
|
|
|
|
if lastWasBlank {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
lastWasBlank = true
|
|
|
|
} else {
|
|
|
|
lastWasBlank = false
|
|
|
|
}
|
|
|
|
|
|
|
|
out = append(out, line)
|
|
|
|
}
|
|
|
|
return strings.Join(out, "\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
generateUnitTestWorkflows()
|
2021-12-14 23:26:20 +03:00
|
|
|
generateClusterWorkflows(clusterList, clusterTestTemplateFormatStr)
|
|
|
|
generateClusterWorkflows(clusterDockerList, clusterTestDockerTemplate)
|
2021-08-30 09:00:03 +03:00
|
|
|
|
|
|
|
// tests that will use self-hosted runners
|
|
|
|
err := generateSelfHostedUnitTestWorkflows()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
err = generateSelfHostedClusterWorkflows()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
|
2021-03-02 12:56:44 +03:00
|
|
|
func canonnizeList(list []string) []string {
|
|
|
|
var output []string
|
|
|
|
for _, item := range list {
|
|
|
|
item = strings.TrimSpace(item)
|
|
|
|
if item != "" {
|
|
|
|
output = append(output, item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return output
|
|
|
|
}
|
2021-01-06 17:25:50 +03:00
|
|
|
func parseList(csvList string) []string {
|
|
|
|
var list []string
|
|
|
|
for _, item := range strings.Split(csvList, ",") {
|
2021-11-12 18:21:36 +03:00
|
|
|
if item != "" {
|
|
|
|
list = append(list, strings.TrimSpace(item))
|
|
|
|
}
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
return list
|
|
|
|
}
|
|
|
|
|
2021-08-30 09:00:03 +03:00
|
|
|
func generateSelfHostedUnitTestWorkflows() error {
|
|
|
|
platforms := parseList(unitTestSelfHostedDatabases)
|
|
|
|
for _, platform := range platforms {
|
|
|
|
directoryName := fmt.Sprintf("unit_test_%s", platform)
|
|
|
|
test := &selfHostedTest{
|
2021-09-13 12:12:43 +03:00
|
|
|
Name: fmt.Sprintf("Unit Test (%s)", platform),
|
2021-08-30 09:00:55 +03:00
|
|
|
ImageName: fmt.Sprintf("unit_test_%s", platform),
|
2021-08-30 09:00:03 +03:00
|
|
|
Platform: platform,
|
|
|
|
directoryName: directoryName,
|
2021-09-01 07:03:24 +03:00
|
|
|
Dockerfile: fmt.Sprintf("./.github/docker/%s/Dockerfile", directoryName),
|
2021-08-30 09:00:03 +03:00
|
|
|
MakeTools: true,
|
|
|
|
InstallXtraBackup: false,
|
|
|
|
}
|
|
|
|
err := setupTestDockerFile(test)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-09-13 12:12:43 +03:00
|
|
|
filePath := fmt.Sprintf("%s/unit_test_%s.yml", workflowConfigDir, platform)
|
2021-08-30 09:00:03 +03:00
|
|
|
err = writeFileFromTemplate(unitTestSelfHostedTemplate, filePath, test)
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateSelfHostedClusterWorkflows() error {
|
|
|
|
clusters := canonnizeList(clusterSelfHostedList)
|
|
|
|
for _, cluster := range clusters {
|
|
|
|
directoryName := fmt.Sprintf("cluster_test_%s", cluster)
|
|
|
|
test := &selfHostedTest{
|
2021-09-13 12:12:43 +03:00
|
|
|
Name: fmt.Sprintf("Cluster (%s)", cluster),
|
2021-08-30 09:00:55 +03:00
|
|
|
ImageName: fmt.Sprintf("cluster_test_%s", cluster),
|
2021-08-30 09:00:03 +03:00
|
|
|
Platform: "mysql57",
|
|
|
|
directoryName: directoryName,
|
2021-09-01 07:03:24 +03:00
|
|
|
Dockerfile: fmt.Sprintf("./.github/docker/%s/Dockerfile", directoryName),
|
2021-08-30 09:00:03 +03:00
|
|
|
Shard: cluster,
|
|
|
|
MakeTools: false,
|
|
|
|
InstallXtraBackup: false,
|
|
|
|
}
|
|
|
|
makeToolClusters := canonnizeList(clustersRequiringMakeTools)
|
|
|
|
for _, makeToolCluster := range makeToolClusters {
|
|
|
|
if makeToolCluster == cluster {
|
|
|
|
test.MakeTools = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
xtraBackupClusters := canonnizeList(clustersRequiringXtraBackup)
|
|
|
|
for _, xtraBackupCluster := range xtraBackupClusters {
|
|
|
|
if xtraBackupCluster == cluster {
|
|
|
|
test.InstallXtraBackup = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mysql80Clusters := canonnizeList(clustersRequiringMySQL80)
|
|
|
|
for _, mysql80Cluster := range mysql80Clusters {
|
|
|
|
if mysql80Cluster == cluster {
|
|
|
|
test.Platform = "mysql80"
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err := setupTestDockerFile(test)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-12-14 05:50:50 +03:00
|
|
|
|
2021-09-13 12:12:43 +03:00
|
|
|
filePath := fmt.Sprintf("%s/cluster_endtoend_%s.yml", workflowConfigDir, cluster)
|
2021-08-30 09:00:03 +03:00
|
|
|
err = writeFileFromTemplate(clusterTestSelfHostedTemplate, filePath, test)
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-12-14 23:26:20 +03:00
|
|
|
func generateClusterWorkflows(list []string, tpl string) {
|
|
|
|
clusters := canonnizeList(list)
|
2021-01-06 17:25:50 +03:00
|
|
|
for _, cluster := range clusters {
|
|
|
|
test := &clusterTest{
|
|
|
|
Name: fmt.Sprintf("Cluster (%s)", cluster),
|
|
|
|
Shard: cluster,
|
|
|
|
}
|
2021-03-02 12:56:44 +03:00
|
|
|
makeToolClusters := canonnizeList(clustersRequiringMakeTools)
|
2021-01-06 17:25:50 +03:00
|
|
|
for _, makeToolCluster := range makeToolClusters {
|
|
|
|
if makeToolCluster == cluster {
|
|
|
|
test.MakeTools = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2021-03-02 12:56:44 +03:00
|
|
|
xtraBackupClusters := canonnizeList(clustersRequiringXtraBackup)
|
2021-01-06 17:25:50 +03:00
|
|
|
for _, xtraBackupCluster := range xtraBackupClusters {
|
|
|
|
if xtraBackupCluster == cluster {
|
|
|
|
test.InstallXtraBackup = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2021-08-30 09:00:03 +03:00
|
|
|
ubuntu20Clusters := canonnizeList(clustersRequiringMySQL80)
|
2021-07-14 09:37:33 +03:00
|
|
|
for _, ubuntu20Cluster := range ubuntu20Clusters {
|
|
|
|
if ubuntu20Cluster == cluster {
|
|
|
|
test.Ubuntu20 = true
|
2021-12-14 05:50:50 +03:00
|
|
|
test.Platform = "mysql80"
|
2021-07-14 09:37:33 +03:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2022-03-24 02:11:36 +03:00
|
|
|
if strings.HasPrefix(cluster, "vreplication") || strings.HasSuffix(cluster, "heavy") {
|
2022-03-23 21:42:07 +03:00
|
|
|
test.LimitResourceUsage = true
|
|
|
|
}
|
2021-01-06 17:25:50 +03:00
|
|
|
|
|
|
|
path := fmt.Sprintf("%s/cluster_endtoend_%s.yml", workflowConfigDir, cluster)
|
2021-12-14 23:26:20 +03:00
|
|
|
template := tpl
|
2021-12-14 05:50:50 +03:00
|
|
|
if test.Platform != "" {
|
2022-01-18 13:33:51 +03:00
|
|
|
template = fmt.Sprintf(tpl, "_"+test.Platform)
|
|
|
|
} else if strings.Contains(template, "%s") {
|
|
|
|
template = fmt.Sprintf(tpl, "")
|
2021-12-14 05:50:50 +03:00
|
|
|
}
|
|
|
|
err := writeFileFromTemplate(template, path, test)
|
2021-08-30 09:00:03 +03:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateUnitTestWorkflows() {
|
2021-01-11 00:42:47 +03:00
|
|
|
platforms := parseList(unitTestDatabases)
|
2021-01-06 17:25:50 +03:00
|
|
|
for _, platform := range platforms {
|
|
|
|
test := &unitTest{
|
|
|
|
Name: fmt.Sprintf("Unit Test (%s)", platform),
|
2021-02-05 23:05:29 +03:00
|
|
|
Platform: platform,
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
path := fmt.Sprintf("%s/unit_test_%s.yml", workflowConfigDir, platform)
|
2021-08-30 09:00:03 +03:00
|
|
|
err := writeFileFromTemplate(unitTestTemplate, path, test)
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func setupTestDockerFile(test *selfHostedTest) error {
|
|
|
|
// remove the directory
|
2021-09-01 07:03:24 +03:00
|
|
|
relDirectoryName := fmt.Sprintf("../.github/docker/%s", test.directoryName)
|
2021-08-30 09:00:03 +03:00
|
|
|
err := os.RemoveAll(relDirectoryName)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
2021-08-30 09:00:03 +03:00
|
|
|
// create the directory
|
|
|
|
err = os.MkdirAll(relDirectoryName, 0755)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// generate the docker file
|
|
|
|
dockerFilePath := path.Join(relDirectoryName, "Dockerfile")
|
|
|
|
err = writeFileFromTemplate(dockerFileTemplate, dockerFilePath, test)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
|
2022-03-17 13:08:14 +03:00
|
|
|
func writeFileFromTemplate(templateFile, path string, test any) error {
|
2021-01-06 17:25:50 +03:00
|
|
|
tpl, err := template.ParseFiles(templateFile)
|
|
|
|
if err != nil {
|
2021-08-30 09:00:03 +03:00
|
|
|
return fmt.Errorf("Error: %s\n", err)
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
buf := &bytes.Buffer{}
|
|
|
|
err = tpl.Execute(buf, test)
|
|
|
|
if err != nil {
|
2021-08-30 09:00:03 +03:00
|
|
|
return fmt.Errorf("Error: %s\n", err)
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
f, err := os.Create(path)
|
|
|
|
if err != nil {
|
2021-08-30 09:00:03 +03:00
|
|
|
return fmt.Errorf("Error creating file: %s\n", err)
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|
2021-02-07 02:46:39 +03:00
|
|
|
f.WriteString("# DO NOT MODIFY: THIS FILE IS GENERATED USING \"make generate_ci_workflows\"\n\n")
|
2021-01-06 17:25:50 +03:00
|
|
|
f.WriteString(mergeBlankLines(buf))
|
|
|
|
fmt.Printf("Generated %s\n", path)
|
2021-08-30 09:00:03 +03:00
|
|
|
return nil
|
2021-01-06 17:25:50 +03:00
|
|
|
}
|