From 8bca980920d60f949dae12a2cf21ed9bc14149a6 Mon Sep 17 00:00:00 2001 From: msaf1980 Date: Tue, 22 Nov 2022 18:11:36 +0500 Subject: [PATCH 1/2] e2e tests: update clickhouse versions (21.3, 22.8, latest) --- .github/workflows/tests.yml | 2 +- cmd/e2e-test/carbon_clickhouse.go | 14 +- cmd/e2e-test/clickhouse.go | 181 +++++++++++++++--- cmd/e2e-test/container.go | 67 ++++++- cmd/e2e-test/e2etesting.go | 172 +++++++++-------- cmd/e2e-test/errors.go | 10 + cmd/e2e-test/main.go | 112 ++++++++++- .../plain-nodaily/carbon-clickhouse.conf.tpl | 8 +- tests/plain-nodaily/test.toml | 12 +- tests/plain/carbon-clickhouse.conf.tpl | 8 +- tests/plain/test.toml | 12 +- 11 files changed, 444 insertions(+), 154 deletions(-) create mode 100644 cmd/e2e-test/errors.go diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c537ff9e..19588c0a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -131,4 +131,4 @@ jobs: - name: Integration tests run: | make e2e-test - ./e2e-test -config tests + ./e2e-test -config tests -abort -rmi diff --git a/cmd/e2e-test/carbon_clickhouse.go b/cmd/e2e-test/carbon_clickhouse.go index 1145f662..23ad8612 100644 --- a/cmd/e2e-test/carbon_clickhouse.go +++ b/cmd/e2e-test/carbon_clickhouse.go @@ -21,7 +21,7 @@ type CarbonClickhouse struct { cmd *exec.Cmd `toml:"-"` } -func (c *CarbonClickhouse) Start(clickhouseAddr string) error { +func (c *CarbonClickhouse) Start(clickhouseURL string) error { if c.cmd != nil { return fmt.Errorf("carbon-clickhouse already started") } @@ -52,13 +52,13 @@ func (c *CarbonClickhouse) Start(clickhouseAddr string) error { return err } param := struct { - CLICKHOUSE_ADDR string - CCH_STORE_DIR string - CCH_ADDR string + CLICKHOUSE_URL string + CCH_STORE_DIR string + CCH_ADDR string }{ - CLICKHOUSE_ADDR: clickhouseAddr, - CCH_STORE_DIR: c.storeDir, - CCH_ADDR: c.address, + CLICKHOUSE_URL: clickhouseURL, + CCH_STORE_DIR: c.storeDir, + CCH_ADDR: c.address, } c.configFile = path.Join(c.storeDir, "carbon-clickhouse.conf") diff --git a/cmd/e2e-test/clickhouse.go b/cmd/e2e-test/clickhouse.go index 7789d6f7..6340435d 100644 --- a/cmd/e2e-test/clickhouse.go +++ b/cmd/e2e-test/clickhouse.go @@ -1,99 +1,224 @@ package main import ( + "bytes" + "errors" "fmt" + "io/ioutil" + "net/http" + "os" "os/exec" + "strconv" + "strings" + "time" + + "github.com/msaf1980/go-stringutils" ) var ClickhouseContainerName = "clickhouse-server-gch-test" +var ClickhouseOldImage = "yandex/clickhouse-server" +var ClickhouseDefaultImage = "clickhouse/clickhouse-server" type Clickhouse struct { Version string `toml:"version"` Dir string `toml:"dir"` - Docker string `toml:"docker"` DockerImage string `toml:"image"` - address string `toml:"-"` - container string `toml:"-"` + TZ string `toml:"tz"` // override timezone + + httpAddress string `toml:"-"` + url string `toml:"-"` + container string `toml:"-"` } -func (c *Clickhouse) Start() (error, string) { - if len(c.Version) == 0 { - return fmt.Errorf("version not set"), "" +func (c *Clickhouse) CheckConfig(rootDir string) error { + if c.Version == "" { + c.Version = "latest" } if len(c.Dir) == 0 { - return fmt.Errorf("dir not set"), "" + return ErrNoSetDir } - if len(c.Docker) == 0 { - c.Docker = "docker" + if !strings.HasPrefix(c.Dir, "/") { + c.Dir = rootDir + "/" + c.Dir } - if len(c.DockerImage) == 0 { - c.DockerImage = "yandex/clickhouse-server" + + if c.DockerImage == "" { + if c.Version == "latest" { + c.DockerImage = ClickhouseDefaultImage + } else { + splitV := strings.Split(c.Version, ".") + majorV, err := strconv.Atoi(splitV[0]) + if err != nil { + c.DockerImage = ClickhouseDefaultImage + } else if majorV >= 21 { + c.DockerImage = ClickhouseDefaultImage + } else { + c.DockerImage = ClickhouseOldImage + } + } } + return nil +} + +func (c *Clickhouse) Key() string { + return c.DockerImage + ":" + c.Version + " " + c.Dir + " TZ " + c.TZ +} + +func (c *Clickhouse) Start() (string, error) { var err error - c.address, err = getFreeTCPPort("") + c.httpAddress, err = getFreeTCPPort("") if err != nil { - return err, "" + return "", err } + c.url = "http://" + c.httpAddress c.container = ClickhouseContainerName + // tz, _ := localTZLocationName() + chStart := []string{"run", "-d", "--name", c.container, "--ulimit", "nofile=262144:262144", - "-p", c.address + ":8123", - //"-e", "TZ=UTC", + "-p", c.httpAddress + ":8123", + // "-e", "TZ=" + tz, // workaround for TZ=":/etc/localtime" "-v", c.Dir + "/config.xml:/etc/clickhouse-server/config.xml", "-v", c.Dir + "/users.xml:/etc/clickhouse-server/users.xml", "-v", c.Dir + "/rollup.xml:/etc/clickhouse-server/config.d/rollup.xml", "-v", c.Dir + "/init.sql:/docker-entrypoint-initdb.d/init.sql", - c.DockerImage + ":" + c.Version, + } + if c.TZ != "" { + chStart = append(chStart, "-e", "TZ="+c.TZ) } - cmd := exec.Command(c.Docker, chStart...) + chStart = append(chStart, c.DockerImage+":"+c.Version) + + cmd := exec.Command(DockerBinary, chStart...) out, err := cmd.CombinedOutput() - return err, string(out) + return string(out), err } -func (c *Clickhouse) Stop(delete bool) (error, string) { +func (c *Clickhouse) Stop(delete bool) (string, error) { if len(c.container) == 0 { - return nil, "" + return "", nil } chStop := []string{"stop", c.container} - cmd := exec.Command(c.Docker, chStop...) + cmd := exec.Command(DockerBinary, chStop...) out, err := cmd.CombinedOutput() if err == nil && delete { return c.Delete() } - return err, string(out) + return string(out), err } -func (c *Clickhouse) Delete() (error, string) { +func (c *Clickhouse) Delete() (string, error) { if len(c.container) == 0 { - return nil, "" + return "", nil } chDel := []string{"rm", c.container} - cmd := exec.Command(c.Docker, chDel...) + cmd := exec.Command(DockerBinary, chDel...) out, err := cmd.CombinedOutput() if err == nil { c.container = "" } - return err, string(out) + return string(out), err } -func (c *Clickhouse) Address() string { - return c.address +func (c *Clickhouse) URL() string { + return c.url } func (c *Clickhouse) Container() string { return c.container } + +func (c *Clickhouse) Exec(sql string) (bool, string) { + return containerExec(c.container, []string{"sh", "-c", "clickhouse-client -q '" + sql + "'"}) +} + +func (c *Clickhouse) Query(sql string) (string, error) { + reader := strings.NewReader(sql) + request, err := http.NewRequest("POST", c.URL(), reader) + if err != nil { + return "", err + } + + httpClient := http.Client{ + Timeout: time.Minute, + } + resp, err := httpClient.Do(request) + if err != nil { + return "", err + } + msg, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + if resp.StatusCode != http.StatusOK { + return "", errors.New(resp.Status + ": " + string(bytes.TrimRight(msg, "\n"))) + } + return string(msg), nil +} + +func (c *Clickhouse) Alive() bool { + if len(c.container) == 0 { + return false + } + req, err := http.DefaultClient.Get(c.url) + if err != nil { + return false + } + return req.StatusCode == http.StatusOK +} + +func (c *Clickhouse) CopyLog(destDir string, tail uint64) error { + if len(c.container) == 0 { + return nil + } + dest := destDir + "/clickhouse-server.log" + + chArgs := []string{"cp", c.container + ":/var/log/clickhouse-server/clickhouse-server.log", dest} + + cmd := exec.Command(DockerBinary, chArgs...) + out, err := cmd.CombinedOutput() + if err != nil { + return errors.New(err.Error() + ": " + string(bytes.TrimRight(out, "\n"))) + } + + if tail > 0 { + out, _ := exec.Command("tail", "-"+strconv.FormatUint(tail, 10), dest).Output() + fmt.Fprintf(os.Stderr, "CLICKHOUSE-SERVER.LOG %s", stringutils.UnsafeString(out)) + } + + return nil +} + +func (c *Clickhouse) CopyErrLog(destDir string, tail uint64) error { + if len(c.container) == 0 { + return nil + } + dest := destDir + "/clickhouse-server.err.log" + + chArgs := []string{"cp", c.container + ":/var/log/clickhouse-server/clickhouse-server.err.log", dest} + + cmd := exec.Command(DockerBinary, chArgs...) + out, err := cmd.CombinedOutput() + if err != nil { + return errors.New(err.Error() + ": " + string(bytes.TrimRight(out, "\n"))) + } + + if tail > 0 { + out, _ := exec.Command("tail", "-"+strconv.FormatUint(tail, 10), dest).Output() + fmt.Fprintf(os.Stderr, "CLICKHOUSE-SERVER.ERR %s", stringutils.UnsafeString(out)) + } + + return nil +} diff --git a/cmd/e2e-test/container.go b/cmd/e2e-test/container.go index d0fbaf8c..5640e25e 100644 --- a/cmd/e2e-test/container.go +++ b/cmd/e2e-test/container.go @@ -5,14 +5,71 @@ import ( "strings" ) -func containerExist(dockerBinary, name string) (bool, string) { - if len(dockerBinary) == 0 { - dockerBinary = "docker" +var DockerBinary string + +func imageDelete(image, version string) (bool, string) { + if len(DockerBinary) == 0 { + panic("docker not set") + } + + chArgs := []string{"rmi", image + ":" + version} + + cmd := exec.Command(DockerBinary, chArgs...) + out, err := cmd.CombinedOutput() + s := strings.Trim(string(out), "\n") + + if err == nil { + return true, s + } + + return false, err.Error() + ": " + s +} + +func containerExist(name string) (bool, string) { + if len(DockerBinary) == 0 { + panic("docker not set") } chInspect := []string{"inspect", "--format", "'{{.Name}}'", name} - cmd := exec.Command(dockerBinary, chInspect...) + cmd := exec.Command(DockerBinary, chInspect...) + out, err := cmd.CombinedOutput() + s := strings.Trim(string(out), "\n") + + if err == nil { + return true, s + } + + return false, err.Error() + ": " + s +} + +func containerRemove(name string) (bool, string) { + if len(DockerBinary) == 0 { + panic("docker not set") + } + + chInspect := []string{"rm", "-f", name} + + cmd := exec.Command(DockerBinary, chInspect...) + out, err := cmd.CombinedOutput() + s := strings.Trim(string(out), "\n") + + if err == nil { + return true, s + } + + return false, err.Error() + ": " + s +} + +func containerExec(name string, args []string) (bool, string) { + if len(DockerBinary) == 0 { + panic("docker not set") + } + + dCmd := []string{"exec", name} + dCmd = append(dCmd, args...) + + cmd := exec.Command(DockerBinary, dCmd...) out, err := cmd.CombinedOutput() s := strings.Trim(string(out), "\n") @@ -20,5 +77,5 @@ func containerExist(dockerBinary, name string) (bool, string) { return true, s } - return false, s + return false, err.Error() + ": " + s } diff --git a/cmd/e2e-test/e2etesting.go b/cmd/e2e-test/e2etesting.go index 259f08d8..46c202df 100644 --- a/cmd/e2e-test/e2etesting.go +++ b/cmd/e2e-test/e2etesting.go @@ -23,7 +23,16 @@ const ( InputPlainTCP InputType = iota ) -var inputStrings []string = []string{"tcp_plain"} +var ( + inputStrings []string = []string{"tcp_plain"} + + preSQL = []string{ + "TRUNCATE TABLE IF EXISTS graphite_reverse", + "TRUNCATE TABLE IF EXISTS graphite", + "TRUNCATE TABLE IF EXISTS graphite_index", + "TRUNCATE TABLE IF EXISTS graphite_tags", + } +) func (a *InputType) String() string { return inputStrings[*a] @@ -57,7 +66,9 @@ type TestSchema struct { Verify []Verify `yaml:"verify"` - name string `yaml:"-"` // test alias (from config name) + dir string `yaml:"-"` + name string `yaml:"-"` // test alias (from config name) + chVersions map[string]bool `toml:"-"` } func getFreeTCPPort(name string) (string, error) { @@ -93,11 +104,11 @@ func sendPlain(network, address string, input []string) error { } } -func verifyOut(address string, verify Verify) []string { +func verifyOut(chURL string, verify Verify) []string { var errs []string q := []byte(verify.Query) - req, err := http.NewRequest("POST", "http://"+address+"/", bytes.NewBuffer(q)) + req, err := http.NewRequest("POST", chURL, bytes.NewBuffer(q)) client := &http.Client{Timeout: time.Second * 5} resp, err := client.Do(req) @@ -136,43 +147,29 @@ func verifyOut(address string, verify Verify) []string { } func testCarbonClickhouse( - inputType InputType, test *TestSchema, clickhouse Clickhouse, + inputType InputType, test *TestSchema, clickhouse *Clickhouse, testDir, rootDir string, verbose, breakOnError bool, logger *zap.Logger) (testSuccess bool) { testSuccess = true - clickhouseDir := clickhouse.Dir // for logging - if !strings.HasPrefix(clickhouse.Dir, "/") { - clickhouse.Dir = rootDir + "/" + clickhouse.Dir - } - err, out := clickhouse.Start() + err := clickhouse.CheckConfig(rootDir) if err != nil { - logger.Error("starting clickhouse", - zap.String("config", test.name), - zap.String("input", inputType.String()), - zap.Any("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), - zap.Error(err), - zap.String("out", out), - ) testSuccess = false - clickhouse.Stop(true) return } cch := CarbonClickhouse{ ConfigTpl: testDir + "/" + test.ConfigTpl, } - err = cch.Start(clickhouse.Address()) + err = cch.Start(clickhouse.URL()) if err != nil { logger.Error("starting carbon-clickhouse", zap.String("config", test.name), zap.String("input", inputType.String()), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), zap.Error(err), - zap.String("out", out), ) testSuccess = false } @@ -182,7 +179,7 @@ func testCarbonClickhouse( zap.String("config", test.name), zap.String("input", inputType.String()), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), ) time.Sleep(2 * time.Second) // Run test @@ -199,12 +196,12 @@ func testCarbonClickhouse( zap.String("config", test.name), zap.String("input", inputType.String()), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), zap.Error(err), ) testSuccess = false if breakOnError { - debug(test, &clickhouse, &cch) + debug(test, clickhouse, &cch) } } } @@ -213,7 +210,7 @@ func testCarbonClickhouse( verifyFailed := 0 time.Sleep(10 * time.Second) for _, verify := range test.Verify { - if errs := verifyOut(clickhouse.Address(), verify); len(errs) > 0 { + if errs := verifyOut(clickhouse.URL(), verify); len(errs) > 0 { testSuccess = false verifyFailed++ for _, e := range errs { @@ -223,18 +220,18 @@ func testCarbonClickhouse( zap.String("config", test.name), zap.String("input", inputType.String()), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), zap.String("verify", verify.Query), ) if breakOnError { - debug(test, &clickhouse, &cch) + debug(test, clickhouse, &cch) } } else if verbose { logger.Info("verify records in clickhouse", zap.String("config", test.name), zap.String("input", inputType.String()), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), zap.String("verify", verify.Query), ) } @@ -244,7 +241,7 @@ func testCarbonClickhouse( zap.String("config", test.name), zap.String("input", inputType.String()), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), zap.Int("verify failed", verifyFailed), zap.Int("verify total", len(test.Verify)), ) @@ -253,7 +250,7 @@ func testCarbonClickhouse( zap.String("config", test.name), zap.String("input", inputType.String()), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), zap.Int("verify success", len(test.Verify)), zap.Int("verify total", len(test.Verify)), ) @@ -268,22 +265,8 @@ func testCarbonClickhouse( zap.String("config", test.name), zap.String("input", inputType.String()), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), zap.Error(err), - zap.String("out", out), - ) - testSuccess = false - } - - err, out = clickhouse.Stop(true) - if err != nil { - logger.Error("stoping clickhouse", - zap.String("config", test.name), - zap.String("input", inputType.String()), - zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), - zap.Error(err), - zap.String("out", out), ) testSuccess = false } @@ -294,7 +277,7 @@ func testCarbonClickhouse( zap.String("input", inputType.String()), zap.String("status", "success"), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), ) } else { logger.Error("end e2e test", @@ -302,62 +285,97 @@ func testCarbonClickhouse( zap.String("input", inputType.String()), zap.String("status", "failed"), zap.String("clickhouse version", clickhouse.Version), - zap.String("clickhouse config", clickhouseDir), + zap.String("clickhouse config", clickhouse.Dir), ) } return } -func runTest(config string, rootDir string, verbose, breakOnError bool, logger *zap.Logger) (failed, total int) { - testDir := path.Dir(config) - d, err := ioutil.ReadFile(config) +func clickhouseStart(clickhouse *Clickhouse, logger *zap.Logger) bool { + out, err := clickhouse.Start() if err != nil { - logger.Error("failed to read config", - zap.String("config", config), + logger.Error("starting clickhouse", + zap.Any("clickhouse version", clickhouse.Version), + zap.String("clickhouse config", clickhouse.Dir), zap.Error(err), + zap.String("out", out), ) - failed++ - total++ - return + clickhouse.Stop(true) + return false } + return true +} - confShort := strings.ReplaceAll(config, rootDir+"/", "") +func clickhouseStop(clickhouse *Clickhouse, logger *zap.Logger) (result bool) { + result = true + if !clickhouse.Alive() { + clickhouse.CopyLog(os.TempDir(), 10) + result = false + } - var cfg = MainConfig{} - if _, err := toml.Decode(string(d), &cfg); err != nil { - logger.Fatal("failed to decode config", - zap.String("config", confShort), + out, err := clickhouse.Stop(true) + if err != nil { + logger.Error("stoping clickhouse", + zap.String("clickhouse version", clickhouse.Version), + zap.String("clickhouse config", clickhouse.Dir), zap.Error(err), + zap.String("out", out), ) + result = false } + return result +} - cfg.Test.name = confShort +func loadConfig(config string, rootDir string) (*MainConfig, error) { + d, err := ioutil.ReadFile(config) + if err != nil { + return nil, err + } + + var cfg = &MainConfig{} + if _, err := toml.Decode(string(d), cfg); err != nil { + return nil, err + } + + cfg.Test.dir = path.Dir(config) + cfg.Test.name = strings.ReplaceAll(config, rootDir+"/", "") if len(cfg.Test.InputTypes) == 0 { cfg.Test.InputTypes = []InputType{InputPlainTCP} } if len(cfg.Test.Input) == 0 { - logger.Fatal("input not set", - zap.String("config", confShort), - ) + return nil, ErrNoInput } - for _, clickhouse := range cfg.Test.Clickhouse { - if exist, out := containerExist(clickhouse.Docker, ClickhouseContainerName); exist { - logger.Error("clickhouse already exist", - zap.String("container", ClickhouseContainerName), + cfg.Test.chVersions = make(map[string]bool) + for i := range cfg.Test.Clickhouse { + if err := cfg.Test.Clickhouse[i].CheckConfig(rootDir); err == nil { + cfg.Test.chVersions[cfg.Test.Clickhouse[i].Key()] = true + } else { + return nil, fmt.Errorf("[%d] %s", i, err.Error()) + } + } + return cfg, nil +} + +func runTest(cfg *MainConfig, clickhouse *Clickhouse, rootDir string, verbose, breakOnError bool, logger *zap.Logger) (failed, total int) { + for _, sql := range preSQL { + if success, out := clickhouse.Exec(sql); !success { + logger.Error("pre-execute", + zap.String("config", cfg.Test.name), + zap.Any("clickhouse version", clickhouse.Version), + zap.String("clickhouse config", clickhouse.Dir), + zap.String("sql", sql), zap.String("out", out), ) - failed++ - total++ - continue + return } - for _, inputType := range cfg.Test.InputTypes { - total++ - if !testCarbonClickhouse(inputType, cfg.Test, clickhouse, testDir, rootDir, verbose, breakOnError, logger) { - failed++ - } + } + for _, inputType := range cfg.Test.InputTypes { + total++ + if !testCarbonClickhouse(inputType, cfg.Test, clickhouse, cfg.Test.dir, rootDir, verbose, breakOnError, logger) { + failed++ } } diff --git a/cmd/e2e-test/errors.go b/cmd/e2e-test/errors.go new file mode 100644 index 00000000..5cd1aa36 --- /dev/null +++ b/cmd/e2e-test/errors.go @@ -0,0 +1,10 @@ +package main + +import "errors" + +var ( + ErrTimestampInvalid = errors.New("invalid timestamp") + ErrNoTest = errors.New("no test section") + ErrNoSetDir = errors.New("dir not set") + ErrNoInput = errors.New("input not set") +) diff --git a/cmd/e2e-test/main.go b/cmd/e2e-test/main.go index 518935f8..87902fd3 100644 --- a/cmd/e2e-test/main.go +++ b/cmd/e2e-test/main.go @@ -7,6 +7,7 @@ import ( "os" "path" "runtime" + "time" "go.uber.org/zap" ) @@ -47,7 +48,7 @@ func expandDir(dirname string, paths *[]string) error { return nil } -func expand(filename string, paths *[]string) error { +func expandFilename(filename string, paths *[]string) error { if len(filename) == 0 { return nil } @@ -71,30 +72,125 @@ func main() { config := flag.String("config", "", "toml configuration file or dir where toml files is searched (recursieve)") verbose := flag.Bool("verbose", false, "verbose") breakOnError := flag.Bool("break", false, "break and wait user response if request failed") + abortOnError := flag.Bool("abort", false, "abort tests if test failed") + cleanup := flag.Bool("cleanup", false, "delete containers if exists before start") + rmi := flag.Bool("rmi", false, "delete images after test end (for low space usage))") flag.Parse() logger, err := zap.NewProduction() if err != nil { log.Fatal(err) } - var configs []string - err = expand(*config, &configs) + DockerBinary = os.Getenv("DOCKER_E2E") + if DockerBinary == "" { + DockerBinary = "docker" + } + + if *cleanup { + if exist, _ := containerExist(ClickhouseContainerName); exist { + if ok, out := containerRemove(ClickhouseContainerName); !ok { + logger.Fatal("failed to cleanup", + zap.String("container", ClickhouseContainerName), + zap.String("error", out), + ) + os.Exit(1) + } + } + if len(*config) == 0 { + return + } + } + + var allConfigs []string + err = expandFilename(*config, &allConfigs) if err != nil { logger.Fatal( "config", zap.Error(err), ) } - if len(configs) == 0 { + if len(allConfigs) == 0 { logger.Fatal("config should be non-null") } + chVersions := make(map[string]Clickhouse) + configs := make([]*MainConfig, 0, len(allConfigs)) + for _, config := range allConfigs { + cfg, err := loadConfig(config, rootDir) + if err == nil { + configs = append(configs, cfg) + for _, ch := range cfg.Test.Clickhouse { + chVersions[ch.Key()] = ch + } + } else { + logger.Error("failed to read config", + zap.String("config", config), + zap.Error(err), + zap.Any("decode", cfg), + ) + } + } + failed := 0 total := 0 - for _, config := range configs { - testFailed, testTotal := runTest(config, rootDir, *verbose, *breakOnError, logger) - failed += testFailed - total += testTotal + for chVersion := range chVersions { + ch := chVersions[chVersion] + if exist, out := containerExist(ClickhouseContainerName); exist { + logger.Error("clickhouse already exist", + zap.String("container", ClickhouseContainerName), + zap.String("out", out), + ) + os.Exit(1) + } + + logger.Info("clickhouse", + zap.Any("clickhouse image", ch.DockerImage), + zap.Any("clickhouse version", ch.Version), + zap.String("clickhouse config", ch.Dir), + zap.String("tz", ch.TZ), + ) + if clickhouseStart(&ch, logger) { + time.Sleep(100 * time.Millisecond) + for i := 200; i < 3000; i += 200 { + if ch.Alive() { + break + } + time.Sleep(time.Duration(i) * time.Millisecond) + } + if !ch.Alive() { + logger.Error("starting clickhouse", + zap.Any("clickhouse version", ch.Version), + zap.String("clickhouse config", ch.Dir), + zap.String("error", "clickhouse is down"), + ) + failed++ + total++ + } else { + for _, config := range configs { + if config.Test.chVersions[chVersion] { + testFailed, testTotal := runTest(config, &ch, rootDir, *verbose, *breakOnError, logger) + failed += testFailed + total += testTotal + } + } + } + if !clickhouseStop(&ch, logger) { + failed++ + } + } + + if *rmi { + if success, out := imageDelete(ch.DockerImage, ch.Version); !success { + logger.Error("docker remove image", + zap.Any("clickhouse version", ch.Version), + zap.String("clickhouse config", ch.Dir), + zap.String("out", out), + ) + } + } + if *abortOnError && failed > 0 { + break + } } if failed > 0 { diff --git a/tests/plain-nodaily/carbon-clickhouse.conf.tpl b/tests/plain-nodaily/carbon-clickhouse.conf.tpl index 7da39d6f..9c1b5e41 100644 --- a/tests/plain-nodaily/carbon-clickhouse.conf.tpl +++ b/tests/plain-nodaily/carbon-clickhouse.conf.tpl @@ -9,7 +9,7 @@ chunk-auto-interval = "" [upload.graphite_index] type = "index" table = "graphite_index" -url = "http://{{ .CLICKHOUSE_ADDR }}/" +url = "{{ .CLICKHOUSE_URL }}/" timeout = "2m30s" cache-ttl = "1h" disable-daily-index = true @@ -18,21 +18,21 @@ disable-daily-index = true type = "tagged" table = "graphite_tags" threads = 3 -url = "http://{{ .CLICKHOUSE_ADDR }}/" +url = "{{ .CLICKHOUSE_URL }}/" timeout = "2m30s" cache-ttl = "1h" [upload.graphite_reverse] type = "points-reverse" table = "graphite_reverse" -url = "http://{{ .CLICKHOUSE_ADDR }}/" +url = "{{ .CLICKHOUSE_URL }}/" timeout = "2m30s" zero-timestamp = true [upload.graphite] type = "points" table = "graphite" -url = "http://{{ .CLICKHOUSE_ADDR }}/" +url = "{{ .CLICKHOUSE_URL }}/" timeout = "2m30s" zero-timestamp = true diff --git a/tests/plain-nodaily/test.toml b/tests/plain-nodaily/test.toml index 70a77246..6c480342 100644 --- a/tests/plain-nodaily/test.toml +++ b/tests/plain-nodaily/test.toml @@ -92,19 +92,11 @@ input = [ ] [[test.clickhouse]] -version = "19.14" -dir = "tests/clickhouse/rollup" - -[[test.clickhouse]] -version = "20.3" -dir = "tests/clickhouse/rollup" - -[[test.clickhouse]] -version = "20.8" +version = "21.3" dir = "tests/clickhouse/rollup" [[test.clickhouse]] -version = "21.3" +version = "22.8" dir = "tests/clickhouse/rollup" [[test.clickhouse]] diff --git a/tests/plain/carbon-clickhouse.conf.tpl b/tests/plain/carbon-clickhouse.conf.tpl index 3e93d859..c97d7384 100644 --- a/tests/plain/carbon-clickhouse.conf.tpl +++ b/tests/plain/carbon-clickhouse.conf.tpl @@ -9,7 +9,7 @@ chunk-auto-interval = "" [upload.graphite_index] type = "index" table = "graphite_index" -url = "http://{{ .CLICKHOUSE_ADDR }}/" +url = "{{ .CLICKHOUSE_URL }}/" timeout = "2m30s" cache-ttl = "1h" @@ -17,21 +17,21 @@ cache-ttl = "1h" type = "tagged" table = "graphite_tags" threads = 3 -url = "http://{{ .CLICKHOUSE_ADDR }}/" +url = "{{ .CLICKHOUSE_URL }}/" timeout = "2m30s" cache-ttl = "1h" [upload.graphite_reverse] type = "points-reverse" table = "graphite_reverse" -url = "http://{{ .CLICKHOUSE_ADDR }}/" +url = "{{ .CLICKHOUSE_URL }}/" timeout = "2m30s" zero-timestamp = true [upload.graphite] type = "points" table = "graphite" -url = "http://{{ .CLICKHOUSE_ADDR }}/" +url = "{{ .CLICKHOUSE_URL }}/" timeout = "2m30s" zero-timestamp = true diff --git a/tests/plain/test.toml b/tests/plain/test.toml index 30163b28..591b7038 100644 --- a/tests/plain/test.toml +++ b/tests/plain/test.toml @@ -94,19 +94,11 @@ input = [ ] [[test.clickhouse]] -version = "19.14" -dir = "tests/clickhouse/rollup" - -[[test.clickhouse]] -version = "20.3" -dir = "tests/clickhouse/rollup" - -[[test.clickhouse]] -version = "20.8" +version = "21.3" dir = "tests/clickhouse/rollup" [[test.clickhouse]] -version = "21.3" +version = "22.8" dir = "tests/clickhouse/rollup" [[test.clickhouse]] From 5999391bc95afd44fe3a594d3b1c2571d2cf670a Mon Sep 17 00:00:00 2001 From: msaf1980 Date: Tue, 22 Nov 2022 18:19:18 +0500 Subject: [PATCH 2/2] deprecate golang < 1.18 --- .github/workflows/tests.yml | 4 ---- README.md | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 19588c0a..b1175f73 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,11 +16,7 @@ jobs: strategy: matrix: go: - - ^1.15 - - ^1.16 - - ^1.17 - ^1.18 - - ^1.19 - ^1 steps: diff --git a/README.md b/README.md index c1be17c9..fa19b077 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ Last releases are stable and ready for production use Docker images are available on [packages](https://github.com/lomik/carbon-clickhouse/pkgs/container/carbon-clickhouse) page. ## Build + +Required golang 1.18+ + ```sh # build binary git clone https://github.com/lomik/carbon-clickhouse.git