Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ CLI flags take precedence over environment variables.
| `--test-discovery-cache` | `DD_TEST_OPTIMIZATION_RUNNER_TEST_DISCOVERY_CACHE` | | `""` | Path to a restored test discovery cache file. DDTest imports it before planning and refreshes the internal discovery cache after successful full discovery. |
| `--force-full-test-discovery` | `DD_TEST_OPTIMIZATION_RUNNER_FORCE_FULL_TEST_DISCOVERY` | | `false` | Force full test discovery when the framework supports it, including in suite-level skipping mode. |
| `--strict-discovery` | `DD_TEST_OPTIMIZATION_RUNNER_STRICT_DISCOVERY` | | `false` | Fail planning when full test discovery fails. Cancelled full discovery still uses fast test file discovery fallback. |
| `--runtime-tags` | `DD_TEST_OPTIMIZATION_RUNNER_RUNTIME_TAGS` | | `""` | JSON string to override runtime tags used to fetch skippable tests. Useful for local development on a different OS than CI, such as `--runtime-tags '{"os.platform":"linux","runtime.version":"3.2.0"}'`. |
| `--runtime-tags` | `DD_TEST_OPTIMIZATION_RUNNER_RUNTIME_TAGS` | `DD_TEST_OPTIMIZATION_RUNTIME_TAGS` | `""` | JSON string to override runtime tags used to fetch skippable tests. Useful for local development on a different OS than CI, such as `--runtime-tags '{"os.platform":"linux","runtime.version":"3.2.0"}'`. |
| | `DD_TEST_OPTIMIZATION_RUNNER_REPORT_ENABLED` | | `true` | Print human-readable plan and run reports. Set to `false` to disable them. |
18 changes: 17 additions & 1 deletion internal/settings/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,25 @@ const (
defaultCiNodeWorkers = 1
defaultParallelRunnerOverhead = 25 * time.Second
ncpuCiNodeWorkers = "ncpu"
envPrefix = "DD_TEST_OPTIMIZATION_RUNNER"
platformEnv = "DD_TEST_OPTIMIZATION_RUNNER_PLATFORM"
frameworkEnv = "DD_TEST_OPTIMIZATION_RUNNER_FRAMEWORK"
minParallelismEnv = "DD_TEST_OPTIMIZATION_RUNNER_MIN_PARALLELISM"
maxParallelismEnv = "DD_TEST_OPTIMIZATION_RUNNER_MAX_PARALLELISM"
parallelRunnerOverheadEnv = "DD_TEST_OPTIMIZATION_RUNNER_CI_JOB_OVERHEAD"
workerEnv = "DD_TEST_OPTIMIZATION_RUNNER_WORKER_ENV"
ciNodeEnv = "DD_TEST_OPTIMIZATION_RUNNER_CI_NODE"
ciNodeWorkersEnv = "DD_TEST_OPTIMIZATION_RUNNER_CI_NODE_WORKERS"
commandEnv = "DD_TEST_OPTIMIZATION_RUNNER_COMMAND"
testsLocationEnv = "DD_TEST_OPTIMIZATION_RUNNER_TESTS_LOCATION"
testsExcludePatternEnv = "DD_TEST_OPTIMIZATION_RUNNER_TESTS_EXCLUDE_PATTERN"
testDiscoveryCacheEnv = "DD_TEST_OPTIMIZATION_RUNNER_TEST_DISCOVERY_CACHE"
testSkippingModeEnv = "DD_TESTOPTIMIZATION_TIA_TEST_SKIPPING_MODE"
forceFullTestDiscoveryEnv = "DD_TEST_OPTIMIZATION_RUNNER_FORCE_FULL_TEST_DISCOVERY"
strictDiscoveryEnv = "DD_TEST_OPTIMIZATION_RUNNER_STRICT_DISCOVERY"
runtimeTagsEnv = "DD_TEST_OPTIMIZATION_RUNNER_RUNTIME_TAGS"
runtimeTagsAliasEnv = "DD_TEST_OPTIMIZATION_RUNTIME_TAGS"
reportEnabledEnv = "DD_TEST_OPTIMIZATION_RUNNER_REPORT_ENABLED"
knapsackTestFilePatternEnv = "KNAPSACK_PRO_TEST_FILE_PATTERN"
knapsackTestFileExcludeEnv = "KNAPSACK_PRO_TEST_FILE_EXCLUDE_PATTERN"
)
Expand Down Expand Up @@ -120,7 +132,7 @@ var (

func Init() {
viper.AutomaticEnv()
viper.SetEnvPrefix("DD_TEST_OPTIMIZATION_RUNNER")
viper.SetEnvPrefix(envPrefix)
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
if err := viper.BindEnv("parallel_runner_overhead", parallelRunnerOverheadEnv); err != nil {
fmt.Fprintf(os.Stderr, "Error binding parallel runner overhead env: %v\n", err)
Expand Down Expand Up @@ -150,6 +162,10 @@ func Init() {
fmt.Fprintf(os.Stderr, "Error binding strict discovery env: %v\n", err)
os.Exit(1)
}
if err := viper.BindEnv("runtime_tags", runtimeTagsEnv, runtimeTagsAliasEnv); err != nil {
fmt.Fprintf(os.Stderr, "Error binding runtime tags env: %v\n", err)
os.Exit(1)
}

setDefaults()

Expand Down
100 changes: 68 additions & 32 deletions internal/settings/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,41 +288,41 @@ func TestEnvironmentVariables(t *testing.T) {
viper.Reset()

// Set environment variables
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_PLATFORM", "python")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_FRAMEWORK", "pytest")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_MIN_PARALLELISM", "2")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_MAX_PARALLELISM", "8")
_ = os.Setenv(platformEnv, "python")
_ = os.Setenv(frameworkEnv, "pytest")
_ = os.Setenv(minParallelismEnv, "2")
_ = os.Setenv(maxParallelismEnv, "8")
_ = os.Setenv(parallelRunnerOverheadEnv, "40s")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_WORKER_ENV", "RAILS_DB=my_project_dev_{{nodeIndex}}")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_CI_NODE", "5")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_CI_NODE_WORKERS", "4")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_COMMAND", "bundle exec rspec")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_TESTS_LOCATION", "spec/**/*_spec.rb")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_TESTS_EXCLUDE_PATTERN", "spec/system/**/*_spec.rb")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_TEST_DISCOVERY_CACHE", "/tmp/ddtest-tests.json")
_ = os.Setenv("DD_TESTOPTIMIZATION_TIA_TEST_SKIPPING_MODE", "suite")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_FORCE_FULL_TEST_DISCOVERY", "true")
_ = os.Setenv(workerEnv, "RAILS_DB=my_project_dev_{{nodeIndex}}")
_ = os.Setenv(ciNodeEnv, "5")
_ = os.Setenv(ciNodeWorkersEnv, "4")
_ = os.Setenv(commandEnv, "bundle exec rspec")
_ = os.Setenv(testsLocationEnv, "spec/**/*_spec.rb")
_ = os.Setenv(testsExcludePatternEnv, "spec/system/**/*_spec.rb")
_ = os.Setenv(testDiscoveryCacheEnv, "/tmp/ddtest-tests.json")
_ = os.Setenv(testSkippingModeEnv, "suite")
_ = os.Setenv(forceFullTestDiscoveryEnv, "true")
_ = os.Setenv(strictDiscoveryEnv, "true")
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_RUNTIME_TAGS", `{"os.platform":"linux","runtime.version":"3.2.0"}`)
_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_REPORT_ENABLED", "false")
_ = os.Setenv(runtimeTagsEnv, `{"os.platform":"linux","runtime.version":"3.2.0"}`)
_ = os.Setenv(reportEnabledEnv, "false")
defer func() {
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_PLATFORM")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_FRAMEWORK")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_MIN_PARALLELISM")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_MAX_PARALLELISM")
_ = os.Unsetenv(platformEnv)
_ = os.Unsetenv(frameworkEnv)
_ = os.Unsetenv(minParallelismEnv)
_ = os.Unsetenv(maxParallelismEnv)
_ = os.Unsetenv(parallelRunnerOverheadEnv)
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_WORKER_ENV")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_CI_NODE")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_CI_NODE_WORKERS")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_COMMAND")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_TESTS_LOCATION")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_TESTS_EXCLUDE_PATTERN")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_TEST_DISCOVERY_CACHE")
_ = os.Unsetenv("DD_TESTOPTIMIZATION_TIA_TEST_SKIPPING_MODE")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_FORCE_FULL_TEST_DISCOVERY")
_ = os.Unsetenv(workerEnv)
_ = os.Unsetenv(ciNodeEnv)
_ = os.Unsetenv(ciNodeWorkersEnv)
_ = os.Unsetenv(commandEnv)
_ = os.Unsetenv(testsLocationEnv)
_ = os.Unsetenv(testsExcludePatternEnv)
_ = os.Unsetenv(testDiscoveryCacheEnv)
_ = os.Unsetenv(testSkippingModeEnv)
_ = os.Unsetenv(forceFullTestDiscoveryEnv)
_ = os.Unsetenv(strictDiscoveryEnv)
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_RUNTIME_TAGS")
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_REPORT_ENABLED")
_ = os.Unsetenv(runtimeTagsEnv)
_ = os.Unsetenv(reportEnabledEnv)
}()

Init()
Expand Down Expand Up @@ -667,6 +667,42 @@ func TestCanonicalTestPatternEnvVarsTakePrecedenceOverKnapsackAliases(t *testing
}
}

func TestRuntimeTagsAlias(t *testing.T) {
config = nil
viper.Reset()

_ = os.Setenv(runtimeTagsEnv, "")
_ = os.Setenv(runtimeTagsAliasEnv, `{"os.platform":"linux","runtime.version":"3.2.0"}`)
defer func() {
_ = os.Unsetenv(runtimeTagsEnv)
_ = os.Unsetenv(runtimeTagsAliasEnv)
}()

Init()

if config.RuntimeTags != `{"os.platform":"linux","runtime.version":"3.2.0"}` {
t.Errorf("expected runtime_tags from alias env var to be JSON string, got %q", config.RuntimeTags)
}
}

func TestCanonicalRuntimeTagsEnvVarTakesPrecedenceOverAlias(t *testing.T) {
config = nil
viper.Reset()

_ = os.Setenv(runtimeTagsEnv, `{"os.platform":"linux"}`)
_ = os.Setenv(runtimeTagsAliasEnv, `{"os.platform":"darwin"}`)
defer func() {
_ = os.Unsetenv(runtimeTagsEnv)
_ = os.Unsetenv(runtimeTagsAliasEnv)
}()

Init()

if config.RuntimeTags != `{"os.platform":"linux"}` {
t.Errorf("expected canonical runtime_tags env var to win, got %q", config.RuntimeTags)
}
}

func TestGetRuntimeTags(t *testing.T) {
config = nil
viper.Reset()
Expand Down Expand Up @@ -938,9 +974,9 @@ func TestEnvironmentVariableCiNodeWorkersNCPU(t *testing.T) {
config = nil
viper.Reset()

_ = os.Setenv("DD_TEST_OPTIMIZATION_RUNNER_CI_NODE_WORKERS", "ncpu")
_ = os.Setenv(ciNodeWorkersEnv, "ncpu")
defer func() {
_ = os.Unsetenv("DD_TEST_OPTIMIZATION_RUNNER_CI_NODE_WORKERS")
_ = os.Unsetenv(ciNodeWorkersEnv)
}()

Init()
Expand Down
Loading