Repository: etcd-io/etcd
File: tests/robustness/main_test.go (Go)

Code before:
	for _, s := range scenarios.Regression(t) {
		t.Run(s.Name, func(t *testing.T) {
			lg := zaptest.NewLogger(t)
			s.Cluster.Logger = lg
			ctx := t.Context()
			c, err := e2e.NewEtcdProcessCluster(ctx, t, e2e.WithConfig(&s.Cluster))
			require.NoError(t, err)
			defer forcestopCluster(c)
			testRobustness(ctx, t, lg, s, c)
		})
	}
}

func testResultsDirectory(t *testing.T) string {
	resultsDirectory, ok := os.LookupEnv("RESULTS_DIR")
	if !ok {
		resultsDirectory = "/tmp/"
	}
	resultsDirectory, err := filepath.Abs(resultsDirectory)
	if err != nil {
		panic(err)
	}
	path, err := filepath.Abs(filepath.Join(
		resultsDirectory, strings.ReplaceAll(t.Name(), "/", "_"), fmt.Sprintf("%v", time.Now().UnixNano())))
	require.NoError(t, err)
	err = os.RemoveAll(path)
	require.NoError(t, err)
	err = os.MkdirAll(path, 0o700)
	require.NoError(t, err)
	return path
}

func testRobustness(ctx context.Context, t *testing.T, lg *zap.Logger, s scenarios.TestScenario, c *e2e.EtcdProcessCluster) {
	r := report.TestReport{Logger: lg, Cluster: c}
	// t.Failed() returns false during panicking. We need to forcibly
	// save data on panicking.
	// Refer to: https://github.com/golang/go/issues/49929
	panicked := true
	defer func() {
		path := testResultsDirectory(t)
		failed := t.Failed()
		_, persistResults := os.LookupEnv("PERSIST_RESULTS")
		if err := r.Report(failed, panicked, persistResults, path); err != nil {
			t.Error(err)
		}
	}()

	r.Client = runScenario(ctx, t, s, lg, c)
	persistedRequests, err := report.PersistedRequestsCluster(lg, c)
	require.NoError(t, err)


Review comment (suggestion):
Robustness tests always delete the directory before using it. Maybe we could do that too. Only difference is that in antithesis container setup we cannot delete the mounted directory. We might want to delete report directory contents.

Code after:
	for _, s := range scenarios.Regression(t) {
		t.Run(s.Name, func(t *testing.T) {
			lg := zaptest.NewLogger(t)
			s.Cluster.Logger = lg
			ctx := t.Context()
			c, err := e2e.NewEtcdProcessCluster(ctx, t, e2e.WithConfig(&s.Cluster))
			require.NoError(t, err)
			defer forcestopCluster(c)
			testRobustness(ctx, t, lg, s, c)
		})
	}
}

func testRobustness(ctx context.Context, t *testing.T, lg *zap.Logger, s scenarios.TestScenario, c *e2e.EtcdProcessCluster) {
	serverDataPaths := report.ServerDataPaths(c)
	r := report.TestReport{Logger: lg, ServersDataPath: serverDataPaths}
	// t.Failed() returns false during panicking. We need to forcibly
	// save data on panicking.
	// Refer to: https://github.com/golang/go/issues/49929
	panicked := true
	defer func() {
		_, persistResults := os.LookupEnv("PERSIST_RESULTS")
		shouldReport := t.Failed() || panicked || persistResults
		path := testResultsDirectory(t)
		if shouldReport {
			if err := r.Report(path); err != nil {
				t.Error(err)
			}
		}
	}()
	r.Client = runScenario(ctx, t, s, lg, c)
	persistedRequests, err := report.PersistedRequestsCluster(lg, c)
	require.NoError(t, err)

	failpointImpactingWatch := s.Failpoint == failpoint.SleepBeforeSendWatchResponse
	if !failpointImpactingWatch {
		watchProgressNotifyEnabled := c.Cfg.ServerConfig.ExperimentalWatchProgressNotifyInterval != 0
		client.ValidateGotAtLeastOneProgressNotify(t, r.Client, s.Watch.RequestProgress || watchProgressNotifyEnabled)
	}
	validateConfig := validate.Config{ExpectRevisionUnique: s.Traffic.ExpectUniqueRevision()}
	result, err := validate.ValidateAndReturnVisualize(lg, validateConfig, r.Client, persistedRequests, 5*time.Minute)
	if err != nil {
		t.Errorf("Validation error: %v", err)
	}
	r.Visualize = result.Linearization.Visualize
	err = result.Error()
	if err != nil {
		t.Error(err)
	}
	panicked = false
}