diff --git a/.circleci/config.yml b/.circleci/config.yml index b0587afacc6..0bdb99adddb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -141,6 +141,7 @@ jobs: command: | export CORTEX_IMAGE_PREFIX="${IMAGE_PREFIX:-quay.io/cortexproject/}" export CORTEX_IMAGE="${CORTEX_IMAGE_PREFIX}cortex:${CIRCLE_TAG:-$(./tools/image-tag)}" + export CORTEX_CHECKOUT_DIR="/home/circleci/.go_workspace/src/github.com/cortexproject/cortex" echo "Running integration tests with image: $CORTEX_IMAGE" go test -timeout 300s -v -count=1 ./integration diff --git a/docs/configuration/single-process-config.yaml b/docs/configuration/single-process-config.yaml index ec4e464a633..2869e95fd4d 100644 --- a/docs/configuration/single-process-config.yaml +++ b/docs/configuration/single-process-config.yaml @@ -37,6 +37,7 @@ ingester: # We want to start immediately and flush on shutdown. join_after: 0 + min_ready_duration: 0s claim_on_rollout: false final_sleep: 0s num_tokens: 512 diff --git a/integration/README.md b/integration/README.md index d47428ccb08..0e98300ba4c 100644 --- a/integration/README.md +++ b/integration/README.md @@ -3,6 +3,7 @@ ## Supported environment variables - `CORTEX_IMAGE`: Docker image used to run Cortex in integration tests (defaults to `quay.io/cortexproject/cortex:latest`) +- `CORTEX_CHECKOUT_DIR`: The absolute path of the Cortex repository local checkout (defaults to `$GOPATH/src/github.com/cortexproject/cortex`) ## Owners diff --git a/integration/backward_compatibility_test.go b/integration/backward_compatibility_test.go index c6bd5512e2b..32b6d67b21e 100644 --- a/integration/backward_compatibility_test.go +++ b/integration/backward_compatibility_test.go @@ -1,9 +1,6 @@ package main import ( - "io/ioutil" - "os" - "path/filepath" "testing" "time" @@ -34,11 +31,7 @@ func TestBackwardCompatibilityWithChunksStorage(t *testing.T) { require.NoError(t, s.StartAndWaitReady(dynamo, consul)) // Start Cortex components (ingester running on previous version). - require.NoError(t, ioutil.WriteFile( - filepath.Join(s.SharedDir(), cortexSchemaConfigFile), - []byte(cortexSchemaConfigYaml), - os.ModePerm), - ) + require.NoError(t, writeFileToSharedDir(s, cortexSchemaConfigFile, []byte(cortexSchemaConfigYaml))) tableManager := e2ecortex.NewTableManager("table-manager", ChunksStorage, previousVersionImage) ingester1 := e2ecortex.NewIngester("ingester-1", consul.NetworkHTTPEndpoint(networkName), ChunksStorage, "") distributor := e2ecortex.NewDistributor("distributor", consul.NetworkHTTPEndpoint(networkName), ChunksStorage, "") diff --git a/integration/configs.go b/integration/configs.go index 4b7418fde64..f7aede0af31 100644 --- a/integration/configs.go +++ b/integration/configs.go @@ -9,7 +9,8 @@ import ( ) const ( - cortexSchemaConfigFile = "chunks-storage-schema-dynamodb.yaml" + cortexConfigFile = "config.yaml" + cortexSchemaConfigFile = "schema.yaml" cortexSchemaConfigYaml = `configs: - from: "2019-03-20" store: aws-dynamo diff --git a/integration/e2e/service_test.go b/integration/e2e/service_test.go index 648986d938a..96cfb7fbe86 100644 --- a/integration/e2e/service_test.go +++ b/integration/e2e/service_test.go @@ -55,7 +55,7 @@ metric_b 1000 defer srv.Close() go func() { - srv.ListenAndServe() + _ = srv.ListenAndServe() }() s := &HTTPService{ @@ -112,7 +112,7 @@ metric_b 1000 defer srv.Close() go func() { - srv.ListenAndServe() + _ = srv.ListenAndServe() }() s := &HTTPService{ diff --git a/integration/e2ecortex/services.go b/integration/e2ecortex/services.go index 3dd47712437..c19597bbda3 100644 --- a/integration/e2ecortex/services.go +++ b/integration/e2ecortex/services.go @@ -103,3 +103,20 @@ func NewTableManager(name string, flags map[string]string, image string) *e2e.HT 80, ) } + +func NewSingleBinary(name string, flags map[string]string, image string, httpPort int, otherPorts ...int) *e2e.HTTPService { + if image == "" { + image = GetDefaultImage() + } + + return e2e.NewHTTPService( + name, + image, + e2e.NewCommandWithoutEntrypoint("cortex", e2e.BuildArgs(e2e.MergeFlags(map[string]string{ + "-log.level": "warn", + }, flags))...), + e2e.NewReadinessProbe(httpPort, "/ready", 204), + httpPort, + otherPorts..., + ) +} diff --git a/integration/getting_started_single_process_config_test.go b/integration/getting_started_single_process_config_test.go new file mode 100644 index 00000000000..7f77e882545 --- /dev/null +++ b/integration/getting_started_single_process_config_test.go @@ -0,0 +1,48 @@ +package main + +import ( + "path/filepath" + "testing" + "time" + + "github.com/prometheus/common/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cortexproject/cortex/integration/e2e" + "github.com/cortexproject/cortex/integration/e2ecortex" +) + +func TestGettingStartedSingleProcessConfig(t *testing.T) { + s, err := e2e.NewScenario(networkName) + require.NoError(t, err) + defer s.Close() + + // Start Cortex components. + require.NoError(t, copyFileToSharedDir(s, "docs/configuration/single-process-config.yaml", cortexConfigFile)) + + // Start Cortex in single binary mode, reading the config from file. + flags := map[string]string{ + "-config.file": filepath.Join(e2e.ContainerSharedDir, cortexConfigFile), + } + + cortex := e2ecortex.NewSingleBinary("cortex-1", flags, "", 9009) + require.NoError(t, s.StartAndWaitReady(cortex)) + + c, err := e2ecortex.NewClient(cortex.Endpoint(9009), cortex.Endpoint(9009), "user-1") + require.NoError(t, err) + + // Push some series to Cortex. + now := time.Now() + series, expectedVector := generateSeries("series_1", now) + + res, err := c.Push(series) + require.NoError(t, err) + require.Equal(t, 200, res.StatusCode) + + // Query the series. + result, err := c.Query("series_1", now) + require.NoError(t, err) + require.Equal(t, model.ValVector, result.Type()) + assert.Equal(t, expectedVector, result.(model.Vector)) +} diff --git a/integration/ingester_flush_test.go b/integration/ingester_flush_test.go index 53016fde9f6..5f8eac4a57d 100644 --- a/integration/ingester_flush_test.go +++ b/integration/ingester_flush_test.go @@ -2,9 +2,6 @@ package main import ( "fmt" - "io/ioutil" - "os" - "path/filepath" "testing" "time" @@ -31,11 +28,7 @@ func TestIngesterFlushWithChunksStorage(t *testing.T) { require.NoError(t, s.StartAndWaitReady(dynamo, consul)) // Start Cortex components. - require.NoError(t, ioutil.WriteFile( - filepath.Join(s.SharedDir(), cortexSchemaConfigFile), - []byte(cortexSchemaConfigYaml), - os.ModePerm), - ) + require.NoError(t, writeFileToSharedDir(s, cortexSchemaConfigFile, []byte(cortexSchemaConfigYaml))) tableManager := e2ecortex.NewTableManager("table-manager", ChunksStorage, "") ingester1 := e2ecortex.NewIngester("ingester-1", consul.NetworkHTTPEndpoint(networkName), mergeFlags(ChunksStorage, map[string]string{ diff --git a/integration/ingester_hand_over_test.go b/integration/ingester_hand_over_test.go index f810aba8d49..085fb8dcabd 100644 --- a/integration/ingester_hand_over_test.go +++ b/integration/ingester_hand_over_test.go @@ -1,9 +1,6 @@ package main import ( - "io/ioutil" - "os" - "path/filepath" "testing" "time" @@ -28,11 +25,8 @@ func TestIngesterHandOverWithChunksStorage(t *testing.T) { dynamo := e2edb.NewDynamoDB() require.NoError(t, s.StartAndWaitReady(dynamo)) - require.NoError(t, ioutil.WriteFile( - filepath.Join(s.SharedDir(), cortexSchemaConfigFile), - []byte(cortexSchemaConfigYaml), - os.ModePerm), - ) + require.NoError(t, writeFileToSharedDir(s, cortexSchemaConfigFile, []byte(cortexSchemaConfigYaml))) + tableManager := e2ecortex.NewTableManager("table-manager", ChunksStorage, "") require.NoError(t, s.StartAndWaitReady(tableManager)) diff --git a/integration/integration_memberlist_single_binary_test.go b/integration/integration_memberlist_single_binary_test.go index 0167d92fe9f..cada1a0a723 100644 --- a/integration/integration_memberlist_single_binary_test.go +++ b/integration/integration_memberlist_single_binary_test.go @@ -1,9 +1,6 @@ package main import ( - "io/ioutil" - "os" - "path/filepath" "testing" "time" @@ -25,11 +22,7 @@ func TestSingleBinaryWithMemberlist(t *testing.T) { // Look ma, no Consul! require.NoError(t, s.StartAndWaitReady(dynamo)) - require.NoError(t, ioutil.WriteFile( - filepath.Join(s.SharedDir(), cortexSchemaConfigFile), - []byte(cortexSchemaConfigYaml), - os.ModePerm), - ) + require.NoError(t, writeFileToSharedDir(s, cortexSchemaConfigFile, []byte(cortexSchemaConfigYaml))) cortex1 := newSingleBinary("cortex-1", "") cortex2 := newSingleBinary("cortex-2", networkName+"-cortex-1:8000") @@ -80,11 +73,10 @@ func newSingleBinary(name string, join string) *e2e.HTTPService { flags["-memberlist.join"] = join } - serv := e2e.NewHTTPService( + serv := e2ecortex.NewSingleBinary( name, - e2ecortex.GetDefaultImage(), - e2e.NewCommandWithoutEntrypoint("cortex", buildArgs(mergeFlags(ChunksStorage, flags))...), - e2e.NewReadinessProbe(80, "/ready", 204), + mergeFlags(ChunksStorage, flags), + "", 80, 8000, ) diff --git a/integration/util.go b/integration/util.go index d9aaa890346..33d3665a83d 100644 --- a/integration/util.go +++ b/integration/util.go @@ -1,6 +1,12 @@ package main import ( + "io/ioutil" + "os" + "path/filepath" + + "github.com/pkg/errors" + "github.com/cortexproject/cortex/integration/e2e" e2edb "github.com/cortexproject/cortex/integration/e2e/db" ) @@ -11,5 +17,28 @@ var ( mergeFlags = e2e.MergeFlags newDynamoClient = e2edb.NewDynamoClient generateSeries = e2e.GenerateSeries - buildArgs = e2e.BuildArgs ) + +func getCortexProjectDir() string { + if dir := os.Getenv("CORTEX_CHECKOUT_DIR"); dir != "" { + return dir + } + + return os.Getenv("GOPATH") + "/src/github.com/cortexproject/cortex" +} + +func writeFileToSharedDir(s *e2e.Scenario, dst string, content []byte) error { + return ioutil.WriteFile( + filepath.Join(s.SharedDir(), dst), + content, + os.ModePerm) +} + +func copyFileToSharedDir(s *e2e.Scenario, src, dst string) error { + content, err := ioutil.ReadFile(filepath.Join(getCortexProjectDir(), src)) + if err != nil { + return errors.Wrapf(err, "unable to read local file %s", src) + } + + return writeFileToSharedDir(s, dst, content) +}