diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 9874afd1a7d..356e54bc7a1 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -22,6 +22,10 @@ https://github.com/elastic/beats/compare/v5.0.0-alpha1...master[Check the HEAD d *Filebeat* +* Default location for the registry file was changed to be `data/registry` from the binary directory, + rather than `.filebeat` in the current working directory. This affects installations for zip/tar.gz/source, + the location for DEB and RPM packages stays the same. {pull}1373[1373] + *Winlogbeat* @@ -59,6 +63,8 @@ https://github.com/elastic/beats/compare/v5.0.0-alpha1...master[Check the HEAD d *Affecting all Beats* +* Configuration options and CLI flags for setting the home, data and config paths. {pull}1373[1373] + *Packetbeat* *Topbeat* diff --git a/filebeat/.gitignore b/filebeat/.gitignore index 8f63df6fca4..88188e565d2 100644 --- a/filebeat/.gitignore +++ b/filebeat/.gitignore @@ -1,7 +1,7 @@ /etc/filebeat.dev.yml .idea .vagrant -.filebeat +/data/ /docs/html_docs filebeat diff --git a/filebeat/config/config.go b/filebeat/config/config.go index b3ca0326dcb..ce34ab08deb 100644 --- a/filebeat/config/config.go +++ b/filebeat/config/config.go @@ -14,7 +14,7 @@ import ( // Defaults for config variables which are not set const ( - DefaultRegistryFile = ".filebeat" + DefaultRegistryFile = "registry" DefaultIgnoreOlderDuration time.Duration = 0 DefaultCloseOlderDuration time.Duration = 1 * time.Hour DefaultScanFrequency time.Duration = 10 * time.Second diff --git a/filebeat/crawler/registrar.go b/filebeat/crawler/registrar.go index 0e81260d922..f31e6a1309b 100644 --- a/filebeat/crawler/registrar.go +++ b/filebeat/crawler/registrar.go @@ -10,6 +10,7 @@ import ( "github.com/elastic/beats/filebeat/input" . "github.com/elastic/beats/filebeat/input" "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/paths" ) type Registrar struct { @@ -46,17 +47,12 @@ func (r *Registrar) Init() error { r.registryFile = cfg.DefaultRegistryFile } - // Make sure the directory where we store the registryFile exists - absPath, err := filepath.Abs(r.registryFile) - if err != nil { - return fmt.Errorf("Failed to get the absolute path of %s: %v", - r.registryFile, err) - } - r.registryFile = absPath + // The registry file is opened in the data path + r.registryFile = paths.Resolve(paths.Data, r.registryFile) // Create directory if it does not already exist. registryPath := filepath.Dir(r.registryFile) - err = os.MkdirAll(registryPath, 0755) + err := os.MkdirAll(registryPath, 0755) if err != nil { return fmt.Errorf("Failed to created registry file dir %s: %v", registryPath, err) @@ -68,7 +64,7 @@ func (r *Registrar) Init() error { } // loadState fetches the previous reading state from the configure RegistryFile file -// The default file is .filebeat file which is stored in the same path as the binary is running +// The default file is `registry` in the data path. func (r *Registrar) LoadState() { if existing, e := os.Open(r.registryFile); e == nil { defer existing.Close() diff --git a/filebeat/docs/migration.asciidoc b/filebeat/docs/migration.asciidoc index db8f12804a5..230c8bd826d 100644 --- a/filebeat/docs/migration.asciidoc +++ b/filebeat/docs/migration.asciidoc @@ -41,7 +41,7 @@ The registry file stores the state and location information that Filebeat uses t where it was last reading. Under Logstash Forwarder, this file was called `.logstash-fowarder`. For Filebeat, the file was renamed. The name varies depending on the package type: - * `.filebeat` for `.tar.gz` and `.tgz` archives + * `data/registry` for `.tar.gz` and `.tgz` archives * `/var/lib/filebeat/registry` for DEB and RPM packages * `c:\ProgramData\filebeat\registry` for the Windows zip file @@ -426,7 +426,7 @@ with the new packages. One notable change is the name of the registry file. The name varies depending on the package type: - * `.filebeat` for `.tar.gz` and `.tgz` archives + * `registry` for `.tar.gz` and `.tgz` archives * `/usr/lib/filebeat/registry` for DEB and RPM packages * `c:\ProgramData\filebeat\registry` for the Windows zip file diff --git a/filebeat/docs/reference/configuration/filebeat-options.asciidoc b/filebeat/docs/reference/configuration/filebeat-options.asciidoc index 0b2cd2ae794..9a8901775cf 100644 --- a/filebeat/docs/reference/configuration/filebeat-options.asciidoc +++ b/filebeat/docs/reference/configuration/filebeat-options.asciidoc @@ -390,13 +390,13 @@ filebeat: ===== registry_file -The name of the registry file. By default, the registry file is put in the current -working directory. If the working directory changes for subsequent runs of Filebeat, indexing starts from the beginning again. +The name of the registry file. If a relative path is used, it is considered relative to the +data path. The default is `registry`. [source,yaml] ------------------------------------------------------------------------------------- filebeat: - registry_file: .filebeat + registry_file: registry ------------------------------------------------------------------------------------- diff --git a/filebeat/etc/beat.yml b/filebeat/etc/beat.yml index bd92c850e1d..ee569ef269a 100644 --- a/filebeat/etc/beat.yml +++ b/filebeat/etc/beat.yml @@ -181,10 +181,9 @@ filebeat: # Flush even though spool_size is not reached. #idle_timeout: 5s - # Name of the registry file. Per default it is put in the current working - # directory. In case the working directory is changed after when running - # filebeat again, indexing starts from the beginning again. - #registry_file: .filebeat + # Name of the registry file. If a relative path is used, it is considered relative to the + # data path. + #registry_file: registry # Full Path to directory with additional prospector configuration files. Each file must end with .yml # These config files must have the full filebeat config part inside, but only diff --git a/filebeat/filebeat.yml b/filebeat/filebeat.yml index 8634eb676ef..1d82d8e8e80 100644 --- a/filebeat/filebeat.yml +++ b/filebeat/filebeat.yml @@ -181,10 +181,9 @@ filebeat: # Flush even though spool_size is not reached. #idle_timeout: 5s - # Name of the registry file. Per default it is put in the current working - # directory. In case the working directory is changed after when running - # filebeat again, indexing starts from the beginning again. - #registry_file: .filebeat + # Name of the registry file. If a relative path is used, it is considered relative to the + # data path. + #registry_file: registry # Full Path to directory with additional prospector configuration files. Each file must end with .yml # These config files must have the full filebeat config part inside, but only diff --git a/filebeat/input/file_test.go b/filebeat/input/file_test.go index e0cbce9f6db..a7891d52e4d 100644 --- a/filebeat/input/file_test.go +++ b/filebeat/input/file_test.go @@ -60,50 +60,50 @@ func TestSafeFileRotateExistingFile(t *testing.T) { assert.NoError(t, os.RemoveAll(tempdir)) }() - // create an existing .filebeat file - err = ioutil.WriteFile(filepath.Join(tempdir, ".filebeat"), + // create an existing registry file + err = ioutil.WriteFile(filepath.Join(tempdir, "registry"), []byte("existing filebeat"), 0x777) assert.NoError(t, err) - // create a new .filebeat.new file - err = ioutil.WriteFile(filepath.Join(tempdir, ".filebeat.new"), + // create a new registry.new file + err = ioutil.WriteFile(filepath.Join(tempdir, "registry.new"), []byte("new filebeat"), 0x777) assert.NoError(t, err) - // rotate .filebeat.new into .filebeat - err = SafeFileRotate(filepath.Join(tempdir, ".filebeat"), - filepath.Join(tempdir, ".filebeat.new")) + // rotate registry.new into registry + err = SafeFileRotate(filepath.Join(tempdir, "registry"), + filepath.Join(tempdir, "registry.new")) assert.NoError(t, err) - contents, err := ioutil.ReadFile(filepath.Join(tempdir, ".filebeat")) + contents, err := ioutil.ReadFile(filepath.Join(tempdir, "registry")) assert.NoError(t, err) assert.Equal(t, []byte("new filebeat"), contents) // do it again to make sure we deal with deleting the old file - err = ioutil.WriteFile(filepath.Join(tempdir, ".filebeat.new"), + err = ioutil.WriteFile(filepath.Join(tempdir, "registry.new"), []byte("new filebeat 1"), 0x777) assert.NoError(t, err) - err = SafeFileRotate(filepath.Join(tempdir, ".filebeat"), - filepath.Join(tempdir, ".filebeat.new")) + err = SafeFileRotate(filepath.Join(tempdir, "registry"), + filepath.Join(tempdir, "registry.new")) assert.NoError(t, err) - contents, err = ioutil.ReadFile(filepath.Join(tempdir, ".filebeat")) + contents, err = ioutil.ReadFile(filepath.Join(tempdir, "registry")) assert.NoError(t, err) assert.Equal(t, []byte("new filebeat 1"), contents) // and again for good measure - err = ioutil.WriteFile(filepath.Join(tempdir, ".filebeat.new"), + err = ioutil.WriteFile(filepath.Join(tempdir, "registry.new"), []byte("new filebeat 2"), 0x777) assert.NoError(t, err) - err = SafeFileRotate(filepath.Join(tempdir, ".filebeat"), - filepath.Join(tempdir, ".filebeat.new")) + err = SafeFileRotate(filepath.Join(tempdir, "registry"), + filepath.Join(tempdir, "registry.new")) assert.NoError(t, err) - contents, err = ioutil.ReadFile(filepath.Join(tempdir, ".filebeat")) + contents, err = ioutil.ReadFile(filepath.Join(tempdir, "registry")) assert.NoError(t, err) assert.Equal(t, []byte("new filebeat 2"), contents) } diff --git a/filebeat/tests/load/filebeat.yml b/filebeat/tests/load/filebeat.yml index 26f7cea3260..2df30ac223b 100644 --- a/filebeat/tests/load/filebeat.yml +++ b/filebeat/tests/load/filebeat.yml @@ -14,7 +14,7 @@ filebeat: spool_size: 4096 idle_timeout: 5s - registry_file: .filebeat + registry_file: registry ############################# Output ########################################## diff --git a/filebeat/tests/system/config/filebeat.yml.j2 b/filebeat/tests/system/config/filebeat.yml.j2 index 648e5e24261..73c9a3d3b5a 100644 --- a/filebeat/tests/system/config/filebeat.yml.j2 +++ b/filebeat/tests/system/config/filebeat.yml.j2 @@ -63,7 +63,9 @@ filebeat: {% endif %} spool_size: idle_timeout: 0.1s - registry_file: {{ beat.working_dir + '/' }}{{ registryFile|default(".filebeat")}} + {% if not skip_registry_config %} + registry_file: {{ beat.working_dir + '/' }}{{ registryFile|default("registry")}} + {%endif%} ############################# Shipper ############################################ @@ -146,4 +148,9 @@ filter: {%- endif %} {% endif %} +{% if path_data %} +path: + data: {{path_data}} +{%endif%} + # vim: set ft=jinja: diff --git a/filebeat/tests/system/config/filebeat_prospectors.yml.j2 b/filebeat/tests/system/config/filebeat_prospectors.yml.j2 index 41869ff15bd..c21b4df5b81 100644 --- a/filebeat/tests/system/config/filebeat_prospectors.yml.j2 +++ b/filebeat/tests/system/config/filebeat_prospectors.yml.j2 @@ -9,7 +9,7 @@ filebeat: encoding: {{prospector.encoding | default("plain") }} {% endfor %} idle_timeout: 0.5s - registry_file: {{ beat.working_dir + '/' }}{{ registryFile|default(".filebeat")}} + registry_file: {{ beat.working_dir + '/' }}{{ registryFile|default("registry")}} output: file: diff --git a/filebeat/tests/system/filebeat.py b/filebeat/tests/system/filebeat.py index 58beae40f2b..a584cb0e234 100644 --- a/filebeat/tests/system/filebeat.py +++ b/filebeat/tests/system/filebeat.py @@ -14,9 +14,9 @@ def setUpClass(self): self.beat_name = "filebeat" super(BaseTest, self).setUpClass() - def get_dot_filebeat(self): - # Returns content of the .filebeat file - dotFilebeat = self.working_dir + '/.filebeat' + def get_registry(self): + # Returns content of the registry file + dotFilebeat = self.working_dir + '/registry' assert os.path.isfile(dotFilebeat) is True with open(dotFilebeat) as file: diff --git a/filebeat/tests/system/test_crawler.py b/filebeat/tests/system/test_crawler.py index a46790c0d18..3e1995860cd 100644 --- a/filebeat/tests/system/test_crawler.py +++ b/filebeat/tests/system/test_crawler.py @@ -251,7 +251,7 @@ def test_file_disappear(self): filebeat.check_kill_and_wait() - data = self.get_dot_filebeat() + data = self.get_registry() # Make sure new file was picked up, old file should stay in assert len(data) == 2 @@ -315,7 +315,7 @@ def test_file_disappear_appear(self): filebeat.check_kill_and_wait() - data = self.get_dot_filebeat() + data = self.get_registry() # Make sure new file was picked up. As it has the same file name, # only one entry exists @@ -373,7 +373,7 @@ def test_force_close(self): filebeat.check_kill_and_wait() - data = self.get_dot_filebeat() + data = self.get_registry() # Make sure new file was picked up. As it has the same file name, # only one entry exists diff --git a/filebeat/tests/system/test_registrar.py b/filebeat/tests/system/test_registrar.py index e78d00a4211..0d4af776395 100644 --- a/filebeat/tests/system/test_registrar.py +++ b/filebeat/tests/system/test_registrar.py @@ -41,12 +41,12 @@ def test_registrar_file_content(self): # the logging and actual writing the file. Seems to happen on Windows. self.wait_until( lambda: os.path.isfile(os.path.join(self.working_dir, - ".filebeat")), + "registry")), max_timeout=1) filebeat.check_kill_and_wait() # Check that a single file exists in the registry. - data = self.get_dot_filebeat() + data = self.get_registry() assert len(data) == 1 logFileAbsPath = os.path.abspath(testfile) @@ -112,12 +112,12 @@ def test_registrar_files(self): # the logging and actual writing the file. Seems to happen on Windows. self.wait_until( lambda: os.path.isfile(os.path.join(self.working_dir, - ".filebeat")), + "registry")), max_timeout=1) filebeat.check_kill_and_wait() # Check that file exist - data = self.get_dot_filebeat() + data = self.get_registry() # Check that 2 files are port of the registrar file assert len(data) == 2 @@ -156,7 +156,7 @@ def test_rotating_file(self): Checks that the registry is properly updated after a file is rotated """ self.render_config_template( - path=os.path.abspath(self.working_dir) + "/log/*" + path=os.path.abspath(self.working_dir) + "/log/*" ) os.mkdir(self.working_dir + "/log/") @@ -167,10 +167,8 @@ def test_rotating_file(self): with open(testfile, 'w') as f: f.write("offset 9\n") - self.wait_until( - lambda: self.output_has(lines=1), - max_timeout=10) - + self.wait_until(lambda: self.output_has(lines=1), + max_timeout=10) testfilerenamed = self.working_dir + "/log/test.1.log" os.rename(testfile, testfilerenamed) @@ -178,15 +176,13 @@ def test_rotating_file(self): with open(testfile, 'w') as f: f.write("offset 10\n") - - self.wait_until( - lambda: self.output_has(lines=2), - max_timeout=10) + self.wait_until(lambda: self.output_has(lines=2), + max_timeout=10) filebeat.check_kill_and_wait() # Check that file exist - data = self.get_dot_filebeat() + data = self.get_registry() # Make sure the offsets are correctly set data[os.path.abspath(testfile)]["offset"] = 10 @@ -194,3 +190,20 @@ def test_rotating_file(self): # Check that 2 files are port of the registrar file assert len(data) == 2 + + def test_data_path(self): + """ + Checks that the registry file is written in a custom data path. + """ + self.render_config_template( + path=self.working_dir + "/test.log", + path_data=self.working_dir + "/datapath", + skip_registry_config=True, + ) + with open(self.working_dir + "/test.log", "w") as f: + f.write("test message\n") + filebeat = self.start_beat() + self.wait_until(lambda: self.output_has(lines=1)) + filebeat.check_kill_and_wait() + + assert os.path.isfile(self.working_dir + "/datapath/registry") diff --git a/libbeat/beat/beat.go b/libbeat/beat/beat.go index 3375d2c4527..cd54556c988 100644 --- a/libbeat/beat/beat.go +++ b/libbeat/beat/beat.go @@ -39,6 +39,7 @@ import ( "github.com/elastic/beats/libbeat/common" "github.com/elastic/beats/libbeat/filter" "github.com/elastic/beats/libbeat/logp" + "github.com/elastic/beats/libbeat/paths" "github.com/elastic/beats/libbeat/publisher" svc "github.com/elastic/beats/libbeat/service" "github.com/satori/go.uuid" @@ -106,6 +107,7 @@ type BeatConfig struct { Logging logp.Logging Shipper publisher.ShipperConfig Filter []filter.FilterConfig + Path paths.Path } // Run initializes and runs a Beater implementation. name is the name of the @@ -179,6 +181,11 @@ func (bc *instance) config() error { return fmt.Errorf("error unpacking config data: %v", err) } + err = paths.InitPaths(&bc.data.Config.Path) + if err != nil { + return fmt.Errorf("error setting default paths: %v", err) + } + err = logp.Init(bc.data.Name, &bc.data.Config.Logging) if err != nil { return fmt.Errorf("error initializing logging: %v", err) @@ -186,6 +193,9 @@ func (bc *instance) config() error { // Disable stderr logging if requested by cmdline flag logp.SetStderr() + // log paths values to help with troubleshooting + logp.Info(paths.Paths.String()) + bc.data.filters, err = filter.New(bc.data.Config.Filter) if err != nil { return fmt.Errorf("error initializing filters: %v", err) diff --git a/libbeat/docs/shared-command-line.asciidoc b/libbeat/docs/shared-command-line.asciidoc index 87a38f4f681..af297eab626 100644 --- a/libbeat/docs/shared-command-line.asciidoc +++ b/libbeat/docs/shared-command-line.asciidoc @@ -39,6 +39,15 @@ Start http server for profiling. This option is useful for troubleshooting and p Write memory profile data to the specified output file. This option is useful for troubleshooting the Beat. +*`-path.config`*:: +Set the default location for configuration (e.g. the Elasticsearch template). + +*`-path.data`*:: +Set the default location for data files. + +*`-path.home`*:: +Set the default location for miscellaneous files. + *`-v`*:: Enable verbose output to show INFO-level messages. diff --git a/libbeat/outputs/elasticsearch/output.go b/libbeat/outputs/elasticsearch/output.go index e9dcdd5071b..9fd5a4fa7b4 100644 --- a/libbeat/outputs/elasticsearch/output.go +++ b/libbeat/outputs/elasticsearch/output.go @@ -13,6 +13,7 @@ import ( "github.com/elastic/beats/libbeat/logp" "github.com/elastic/beats/libbeat/outputs" "github.com/elastic/beats/libbeat/outputs/mode" + "github.com/elastic/beats/libbeat/paths" ) type elasticsearchOutput struct { @@ -131,7 +132,10 @@ func loadTemplate(config Template, clients []mode.ProtocolClient) { // Always takes the first client esClient := clients[0].(*Client) - logp.Info("Loading template enabled. Trying to load template: %v", config.Path) + // Look for the template in the configuration path, if it's not absolute + templatePath := paths.Resolve(paths.Config, config.Path) + + logp.Info("Loading template enabled. Trying to load template: %v", templatePath) exists := esClient.CheckTemplate(config.Name) @@ -143,9 +147,9 @@ func loadTemplate(config Template, clients []mode.ProtocolClient) { } // Load template from file - content, err := ioutil.ReadFile(config.Path) + content, err := ioutil.ReadFile(templatePath) if err != nil { - logp.Err("Could not load template from file path: %s; Error: %s", config.Path, err) + logp.Err("Could not load template from file path: %s; Error: %s", templatePath, err) } else { reader := bytes.NewReader(content) err = esClient.LoadTemplate(config.Name, reader) diff --git a/libbeat/paths/paths.go b/libbeat/paths/paths.go new file mode 100644 index 00000000000..d910726c8ed --- /dev/null +++ b/libbeat/paths/paths.go @@ -0,0 +1,162 @@ +// Package libbeat.paths provides a common way to handle paths +// configuration for all Beats. +// +// Currently the following paths are defined: +// +// path.home - It’s the default folder for everything that doesn't fit in +// the categories below +// +// path.data - Contains things that are expected to change often during normal +// operations (“registry” files, UUID file, etc.) +// +// path.config - Configuration files and Elasticsearch template default location +// +// These settings can be set via the configuration file or via command line flags. +// The CLI flags overwrite the configuration file options. +// +// Use the Resolve function to resolve files to their absolute paths. For example, +// to look for a file in the config path: +// +// cfgfilePath := paths.Resolve(paths.Config, "beat.yml" +package paths + +import ( + "flag" + "fmt" + "os" + "path/filepath" + + "github.com/elastic/beats/libbeat/logp" +) + +var ( + homePath = flag.String("path.home", "", "Home path") + configPath = flag.String("path.config", "", "Configuration path") + dataPath = flag.String("path.data", "", "Data path") +) + +type Path struct { + Home string + Config string + Data string +} + +// FileType is an enumeration type representing the file types. +// Currently existing file types are: Home, Config, Data +type FileType string + +const ( + Home FileType = "home" + Config FileType = "config" + Data FileType = "data" +) + +// Paths is the Path singleton on which the top level functions from this +// package operate. +var Paths = New() + +// New creates a new Paths object with all values set to empty values. +func New() *Path { + return &Path{} +} + +// InitPaths sets the default paths in the configuration based on CLI flags, +// configuration file and default values. It also tries to create the data +// path with mode 0755 and returns an error on failure. +func (paths *Path) InitPaths(cfg *Path) error { + err := paths.initPaths(cfg) + if err != nil { + return err + } + + // make sure the data path exists + err = os.MkdirAll(paths.Data, 0755) + if err != nil { + return fmt.Errorf("Failed to create data path %s: %v", paths.Data, err) + } + + return nil +} + +// InitPaths sets the default paths in the configuration based on CLI flags, +// configuration file and default values. It also tries to create the data +// path with mode 0755 and returns an error on failure. +func InitPaths(cfg *Path) error { + return Paths.InitPaths(cfg) +} + +// initPaths sets the default paths in the configuration based on CLI flags, +// configuration file and default values. +func (paths *Path) initPaths(cfg *Path) error { + paths.Home = cfg.Home + paths.Config = cfg.Config + paths.Data = cfg.Data + + // overwrite paths from CLI flags + if homePath != nil && len(*homePath) > 0 { + paths.Home = *homePath + } + if configPath != nil && len(*configPath) > 0 { + paths.Config = *configPath + } + if dataPath != nil && len(*dataPath) > 0 { + paths.Data = *dataPath + } + + // default for the home path is the binary location + if len(paths.Home) == 0 { + var err error + paths.Home, err = filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + return fmt.Errorf("The absolute path to %s could not be obtained. %v", + os.Args[0], err) + } + } + + // default for config path + if len(paths.Config) == 0 { + paths.Config = paths.Home + } + + // default for data path + if len(paths.Data) == 0 { + paths.Data = filepath.Join(paths.Home, "data") + } + + return nil +} + +// Resolve resolves a path to a location in one of the default +// folders. For example, Resolve(Home, "test") returns an absolute +// path for "test" in the home path. +func (paths *Path) Resolve(fileType FileType, path string) string { + // absolute paths are not changed + if filepath.IsAbs(path) { + return path + } + + switch fileType { + case Home: + return filepath.Join(paths.Home, path) + case Config: + return filepath.Join(paths.Config, path) + case Data: + return filepath.Join(paths.Data, path) + default: + logp.WTF("Unknown file type: %s", fileType) + return "" + } +} + +// Resolve resolves a path to a location in one of the default +// folders. For example, Resolve(Home, "test") returns an absolute +// path for "test" in the home path. +func Resolve(fileType FileType, path string) string { + return Paths.Resolve(fileType, path) +} + +// String returns a textual representation +func (paths *Path) String() string { + return fmt.Sprintf("Home path: [%s] Config path: [%s] Data path: [%s]", + paths.Home, paths.Config, paths.Data) +} diff --git a/libbeat/paths/paths_test.go b/libbeat/paths/paths_test.go new file mode 100644 index 00000000000..9128a2326af --- /dev/null +++ b/libbeat/paths/paths_test.go @@ -0,0 +1,137 @@ +package paths + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestHomePath(t *testing.T) { + type io struct { + CLIHome *string // cli flag home setting + CfgHome string // config file home setting + Path string // requested path + Result string // expected result + ResultData string // expected data path + } + + binDir, err := filepath.Abs(filepath.Dir(os.Args[0])) + assert.NoError(t, err) + tmp := "/tmp/" + + tests := []io{ + { + CLIHome: nil, + CfgHome: "", + Path: "test", + Result: filepath.Join(binDir, "test"), + ResultData: filepath.Join(binDir, "data", "test"), + }, + { + CLIHome: &tmp, + CfgHome: "", + Path: "test", + Result: "/tmp/test", + ResultData: "/tmp/data/test", + }, + { + CLIHome: &tmp, + CfgHome: "/root/", + Path: "test", + Result: "/tmp/test", + ResultData: "/tmp/data/test", + }, + { + CLIHome: nil, + CfgHome: "/root/", + Path: "test", + Result: "/root/test", + ResultData: "/root/data/test", + }, + { + CLIHome: nil, + CfgHome: "/root/", + Path: "/home/test", + Result: "/home/test", + ResultData: "/home/test", + }, + } + + for _, test := range tests { + homePath = test.CLIHome + cfg := Path{Home: test.CfgHome} + assert.NoError(t, Paths.initPaths(&cfg)) + + assert.Equal(t, test.Result, Resolve(Home, test.Path)) + + // config path same as home path + assert.Equal(t, test.Result, Resolve(Config, test.Path)) + + // data path under home path + assert.Equal(t, test.ResultData, Resolve(Data, test.Path)) + } + +} + +func TestDataPath(t *testing.T) { + type io struct { + CLIHome *string // cli flag home setting + CfgHome string // config file home setting + CLIData *string // cli flag for data setting + CfgData string // config file data setting + Path string // requested path + ResultData string // expected data path + } + + binDir, err := filepath.Abs(filepath.Dir(os.Args[0])) + assert.NoError(t, err) + tmp := "/tmp/" + root := "/root/" + + tests := []io{ + { + CLIHome: nil, + CfgHome: "", + CLIData: nil, + CfgData: "", + Path: "test", + ResultData: filepath.Join(binDir, "data", "test"), + }, + { + CLIHome: nil, + CfgHome: "/tmp/", + CLIData: nil, + CfgData: "/root/", + Path: "test", + ResultData: "/root/test", + }, + { + CLIHome: &tmp, + CfgHome: "", + CLIData: nil, + CfgData: "/root/", + Path: "test", + ResultData: "/root/test", + }, + { + CLIHome: &tmp, + CfgHome: "", + CLIData: &root, + CfgData: "/root/data", + Path: "test", + ResultData: "/root/test", + }, + } + + for _, test := range tests { + homePath = test.CLIHome + dataPath = test.CLIData + cfg := Path{Home: test.CfgHome, Data: test.CfgData} + assert.NoError(t, Paths.initPaths(&cfg)) + + assert.Equal(t, test.ResultData, Resolve(Data, test.Path)) + } + +} diff --git a/libbeat/tests/system/beat/beat.py b/libbeat/tests/system/beat/beat.py index 7b952aca832..cf5b8dbe4a6 100644 --- a/libbeat/tests/system/beat/beat.py +++ b/libbeat/tests/system/beat/beat.py @@ -230,7 +230,8 @@ def setUp(self): ) # create working dir - self.working_dir = os.path.join(self.build_path + "run", self.id()) + self.working_dir = os.path.abspath(os.path.join( + self.build_path + "run", self.id())) if os.path.exists(self.working_dir): shutil.rmtree(self.working_dir) os.makedirs(self.working_dir)