package config import ( "testing" "github.com/hashicorp/nomad/ci" "github.com/hashicorp/nomad/helper/pointer" "github.com/shoenig/test/must" ) func TestArtifactConfig_Copy(t *testing.T) { ci.Parallel(t) a := DefaultArtifactConfig() b := a.Copy() must.Equal(t, a, b) must.Equal(t, b, a) b.HTTPReadTimeout = pointer.Of("5m") b.HTTPMaxSize = pointer.Of("2MB") b.GitTimeout = pointer.Of("3m") b.HgTimeout = pointer.Of("2m") must.NotEqual(t, a, b) } func TestArtifactConfig_Merge(t *testing.T) { ci.Parallel(t) testCases := []struct { name string source *ArtifactConfig other *ArtifactConfig expected *ArtifactConfig }{ { name: "merge all fields", source: &ArtifactConfig{ HTTPReadTimeout: pointer.Of("30m"), HTTPMaxSize: pointer.Of("100GB"), GCSTimeout: pointer.Of("30m"), GitTimeout: pointer.Of("30m"), HgTimeout: pointer.Of("30m"), S3Timeout: pointer.Of("30m"), DisableFilesystemIsolation: pointer.Of(false), SetEnvironmentVariables: pointer.Of(""), }, other: &ArtifactConfig{ HTTPReadTimeout: pointer.Of("5m"), HTTPMaxSize: pointer.Of("2GB"), GCSTimeout: pointer.Of("1m"), GitTimeout: pointer.Of("2m"), HgTimeout: pointer.Of("3m"), S3Timeout: pointer.Of("4m"), DisableFilesystemIsolation: pointer.Of(true), SetEnvironmentVariables: pointer.Of("FOO,BAR"), }, expected: &ArtifactConfig{ HTTPReadTimeout: pointer.Of("5m"), HTTPMaxSize: pointer.Of("2GB"), GCSTimeout: pointer.Of("1m"), GitTimeout: pointer.Of("2m"), HgTimeout: pointer.Of("3m"), S3Timeout: pointer.Of("4m"), DisableFilesystemIsolation: pointer.Of(true), SetEnvironmentVariables: pointer.Of("FOO,BAR"), }, }, { name: "null source", source: nil, other: &ArtifactConfig{ HTTPReadTimeout: pointer.Of("5m"), HTTPMaxSize: pointer.Of("2GB"), GCSTimeout: pointer.Of("1m"), GitTimeout: pointer.Of("2m"), HgTimeout: pointer.Of("3m"), S3Timeout: pointer.Of("4m"), DisableFilesystemIsolation: pointer.Of(true), SetEnvironmentVariables: pointer.Of("FOO,BAR"), }, expected: &ArtifactConfig{ HTTPReadTimeout: pointer.Of("5m"), HTTPMaxSize: pointer.Of("2GB"), GCSTimeout: pointer.Of("1m"), GitTimeout: pointer.Of("2m"), HgTimeout: pointer.Of("3m"), S3Timeout: pointer.Of("4m"), DisableFilesystemIsolation: pointer.Of(true), SetEnvironmentVariables: pointer.Of("FOO,BAR"), }, }, { name: "null other", source: &ArtifactConfig{ HTTPReadTimeout: pointer.Of("30m"), HTTPMaxSize: pointer.Of("100GB"), GCSTimeout: pointer.Of("30m"), GitTimeout: pointer.Of("30m"), HgTimeout: pointer.Of("30m"), S3Timeout: pointer.Of("30m"), DisableFilesystemIsolation: pointer.Of(true), SetEnvironmentVariables: pointer.Of("FOO,BAR"), }, other: nil, expected: &ArtifactConfig{ HTTPReadTimeout: pointer.Of("30m"), HTTPMaxSize: pointer.Of("100GB"), GCSTimeout: pointer.Of("30m"), GitTimeout: pointer.Of("30m"), HgTimeout: pointer.Of("30m"), S3Timeout: pointer.Of("30m"), DisableFilesystemIsolation: pointer.Of(true), SetEnvironmentVariables: pointer.Of("FOO,BAR"), }, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { got := tc.source.Merge(tc.other) must.Equal(t, tc.expected, got) }) } } func TestArtifactConfig_Validate(t *testing.T) { ci.Parallel(t) testCases := []struct { name string config func(*ArtifactConfig) expErr string }{ { name: "default config is valid", config: nil, expErr: "", }, { name: "missing http read timeout", config: func(a *ArtifactConfig) { a.HTTPReadTimeout = nil }, expErr: "http_read_timeout must be set", }, { name: "http read timeout is invalid", config: func(a *ArtifactConfig) { a.HTTPReadTimeout = pointer.Of("invalid") }, expErr: "http_read_timeout not a valid duration", }, { name: "http read timeout is empty", config: func(a *ArtifactConfig) { a.HTTPReadTimeout = pointer.Of("") }, expErr: "http_read_timeout not a valid duration", }, { name: "http read timeout is zero", config: func(a *ArtifactConfig) { a.HTTPReadTimeout = pointer.Of("0") }, expErr: "", }, { name: "http read timeout is negative", config: func(a *ArtifactConfig) { a.HTTPReadTimeout = pointer.Of("-10m") }, expErr: "http_read_timeout must be > 0", }, { name: "http max size is missing", config: func(a *ArtifactConfig) { a.HTTPMaxSize = nil }, expErr: "http_max_size must be set", }, { name: "http max size is invalid", config: func(a *ArtifactConfig) { a.HTTPMaxSize = pointer.Of("invalid") }, expErr: "http_max_size not a valid size", }, { name: "http max size is empty", config: func(a *ArtifactConfig) { a.HTTPMaxSize = pointer.Of("") }, expErr: "http_max_size not a valid size", }, { name: "http max size is zero", config: func(a *ArtifactConfig) { a.HTTPMaxSize = pointer.Of("0") }, expErr: "", }, { name: "http max size is negative", config: func(a *ArtifactConfig) { a.HTTPMaxSize = pointer.Of("-l0MB") }, expErr: "http_max_size not a valid size", }, { name: "gcs timeout is missing", config: func(a *ArtifactConfig) { a.GCSTimeout = nil }, expErr: "gcs_timeout must be set", }, { name: "gcs timeout is invalid", config: func(a *ArtifactConfig) { a.GCSTimeout = pointer.Of("invalid") }, expErr: "gcs_timeout not a valid duration", }, { name: "gcs timeout is empty", config: func(a *ArtifactConfig) { a.GCSTimeout = pointer.Of("") }, expErr: "gcs_timeout not a valid duration", }, { name: "gcs timeout is zero", config: func(a *ArtifactConfig) { a.GCSTimeout = pointer.Of("0") }, expErr: "", }, { name: "gcs timeout is negative", config: func(a *ArtifactConfig) { a.GCSTimeout = pointer.Of("-l0m") }, expErr: "gcs_timeout not a valid duration", }, { name: "git timeout is missing", config: func(a *ArtifactConfig) { a.GitTimeout = nil }, expErr: "git_timeout must be set", }, { name: "git timeout is invalid", config: func(a *ArtifactConfig) { a.GitTimeout = pointer.Of("invalid") }, expErr: "git_timeout not a valid duration", }, { name: "git timeout is empty", config: func(a *ArtifactConfig) { a.GitTimeout = pointer.Of("") }, expErr: "git_timeout not a valid duration", }, { name: "git timeout is zero", config: func(a *ArtifactConfig) { a.GitTimeout = pointer.Of("0") }, expErr: "", }, { name: "git timeout is negative", config: func(a *ArtifactConfig) { a.GitTimeout = pointer.Of("-l0m") }, expErr: "git_timeout not a valid duration", }, { name: "hg timeout is missing", config: func(a *ArtifactConfig) { a.HgTimeout = nil }, expErr: "hg_timeout must be set", }, { name: "hg timeout is invalid", config: func(a *ArtifactConfig) { a.HgTimeout = pointer.Of("invalid") }, expErr: "hg_timeout not a valid duration", }, { name: "hg timeout is empty", config: func(a *ArtifactConfig) { a.HgTimeout = pointer.Of("") }, expErr: "hg_timeout not a valid duration", }, { name: "hg timeout is zero", config: func(a *ArtifactConfig) { a.HgTimeout = pointer.Of("0") }, expErr: "", }, { name: "hg timeout is negative", config: func(a *ArtifactConfig) { a.HgTimeout = pointer.Of("-l0m") }, expErr: "hg_timeout not a valid duration", }, { name: "s3 timeout is missing", config: func(a *ArtifactConfig) { a.S3Timeout = nil }, expErr: "s3_timeout must be set", }, { name: "s3 timeout is invalid", config: func(a *ArtifactConfig) { a.S3Timeout = pointer.Of("invalid") }, expErr: "s3_timeout not a valid duration", }, { name: "s3 timeout is empty", config: func(a *ArtifactConfig) { a.S3Timeout = pointer.Of("") }, expErr: "s3_timeout not a valid duration", }, { name: "s3 timeout is zero", config: func(a *ArtifactConfig) { a.S3Timeout = pointer.Of("0") }, expErr: "", }, { name: "s3 timeout is negative", config: func(a *ArtifactConfig) { a.S3Timeout = pointer.Of("-l0m") }, expErr: "s3_timeout not a valid duration", }, { name: "fs isolation not set", config: func(a *ArtifactConfig) { a.DisableFilesystemIsolation = nil }, expErr: "disable_filesystem_isolation must be set", }, { name: "env not set", config: func(a *ArtifactConfig) { a.SetEnvironmentVariables = nil }, expErr: "set_environment_variables must be set", }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { a := DefaultArtifactConfig() if tc.config != nil { tc.config(a) } err := a.Validate() if tc.expErr != "" { must.Error(t, err) must.StrContains(t, err.Error(), tc.expErr) } else { must.NoError(t, err) } }) } }