From 4bdf22eadcd5d3451d592edb8db23cea504b9e75 Mon Sep 17 00:00:00 2001 From: Andrey Meshkov Date: Wed, 15 Apr 2020 14:36:47 +0300 Subject: [PATCH] -: fix autohosts tests on Windows --- util/auto_hosts.go | 70 +++++++++++++++++++++++------------------ util/auto_hosts_test.go | 61 +++++++++++++++++++++++++++-------- 2 files changed, 88 insertions(+), 43 deletions(-) diff --git a/util/auto_hosts.go b/util/auto_hosts.go index 0af5bf08..f310528c 100644 --- a/util/auto_hosts.go +++ b/util/auto_hosts.go @@ -23,7 +23,7 @@ type AutoHosts struct { hostsFn string // path to the main hosts-file hostsDirs []string // paths to OS-specific directories with hosts-files watcher *fsnotify.Watcher // file and directory watcher object - updateChan chan bool // signal for 'update' goroutine + updateChan chan bool // signal for 'updateLoop' goroutine onChanged onChangedT // notification to other modules } @@ -68,20 +68,22 @@ func (a *AutoHosts) Init(hostsFn string) { // Start - start module func (a *AutoHosts) Start() { - go a.update() + log.Debug("Start AutoHosts module") + + go a.updateLoop() a.updateChan <- true go a.watcherLoop() err := a.watcher.Add(a.hostsFn) if err != nil { - log.Error("AutoHosts: %s", err) + log.Error("Error while initializing watcher for a file %s: %s", a.hostsFn, err) } for _, dir := range a.hostsDirs { err = a.watcher.Add(dir) if err != nil { - log.Error("AutoHosts: %s", err) + log.Error("Error while initializing watcher for a directory %s: %s", dir, err) } } } @@ -89,7 +91,8 @@ func (a *AutoHosts) Start() { // Close - close module func (a *AutoHosts) Close() { a.updateChan <- false - a.watcher.Close() + close(a.updateChan) + _ = a.watcher.Close() } // Read IP-hostname pairs from file @@ -174,7 +177,7 @@ func (a *AutoHosts) watcherLoop() { log.Debug("AutoHosts: modified: %s", event.Name) select { case a.updateChan <- true: - // sent a signal to 'update' goroutine + // sent a signal to 'updateLoop' goroutine default: // queue is full } @@ -189,41 +192,48 @@ func (a *AutoHosts) watcherLoop() { } } -// Read static hosts from system files -func (a *AutoHosts) update() { +// updateLoop - read static hosts from system files +func (a *AutoHosts) updateLoop() { for { select { case ok := <-a.updateChan: if !ok { + log.Debug("Finished AutoHosts update loop") return } - table := make(map[string][]net.IP) - - a.load(table, a.hostsFn) - - for _, dir := range a.hostsDirs { - fis, err := ioutil.ReadDir(dir) - if err != nil { - if !os.IsNotExist(err) { - log.Error("AutoHosts: Opening directory: %s: %s", dir, err) - } - continue - } - - for _, fi := range fis { - a.load(table, dir+"/"+fi.Name()) - } - } - - a.lock.Lock() - a.table = table - a.lock.Unlock() - a.notify() + a.updateHosts() } } } +// updateHosts - loads system hosts +func (a *AutoHosts) updateHosts() { + table := make(map[string][]net.IP) + + a.load(table, a.hostsFn) + + for _, dir := range a.hostsDirs { + fis, err := ioutil.ReadDir(dir) + if err != nil { + if !os.IsNotExist(err) { + log.Error("AutoHosts: Opening directory: %s: %s", dir, err) + } + continue + } + + for _, fi := range fis { + a.load(table, dir+"/"+fi.Name()) + } + } + + a.lock.Lock() + a.table = table + a.lock.Unlock() + + a.notify() +} + // Process - get the list of IP addresses for the hostname // Return nil if not found func (a *AutoHosts) Process(host string) []net.IP { diff --git a/util/auto_hosts_test.go b/util/auto_hosts_test.go index ce06e361..4aaa519e 100644 --- a/util/auto_hosts_test.go +++ b/util/auto_hosts_test.go @@ -17,38 +17,73 @@ func prepareTestDir() string { return dir } -func TestAutoHosts(t *testing.T) { +func TestAutoHostsResolution(t *testing.T) { ah := AutoHosts{} dir := prepareTestDir() defer func() { _ = os.RemoveAll(dir) }() f, _ := ioutil.TempFile(dir, "") - defer os.Remove(f.Name()) + defer func() { _ = os.Remove(f.Name()) }() defer f.Close() _, _ = f.WriteString(" 127.0.0.1 host localhost \n") - ah.Init(f.Name()) - ah.Start() - // wait until we parse the file - time.Sleep(50 * time.Millisecond) + // Update from the hosts file + ah.updateHosts() + + // Existing host ips := ah.Process("localhost") - assert.True(t, ips[0].Equal(net.ParseIP("127.0.0.1"))) - ips = ah.Process("newhost") - assert.True(t, ips == nil) + assert.NotNil(t, ips) + assert.Equal(t, 1, len(ips)) + assert.Equal(t, net.ParseIP("127.0.0.1"), ips[0]) + // Unknown host + ips = ah.Process("newhost") + assert.Nil(t, ips) + + // Test hosts file table := ah.List() ips, _ = table["host"] - assert.True(t, ips[0].String() == "127.0.0.1") + assert.NotNil(t, ips) + assert.Equal(t, 1, len(ips)) + assert.Equal(t, "127.0.0.1", ips[0].String()) +} +func TestAutoHostsFSNotify(t *testing.T) { + ah := AutoHosts{} + + dir := prepareTestDir() + defer func() { _ = os.RemoveAll(dir) }() + + f, _ := ioutil.TempFile(dir, "") + defer func() { _ = os.Remove(f.Name()) }() + defer f.Close() + + // Init + _, _ = f.WriteString(" 127.0.0.1 host localhost \n") + ah.Init(f.Name()) + ah.updateHosts() + + // Unknown host + ips := ah.Process("newhost") + assert.Nil(t, ips) + + // Stat monitoring for changes + ah.Start() + defer ah.Close() + + // Update file _, _ = f.WriteString("127.0.0.2 newhost\n") + _ = f.Sync() + // wait until fsnotify has triggerred and processed the file-modification event time.Sleep(50 * time.Millisecond) + // Check if we are notified about changes ips = ah.Process("newhost") - assert.True(t, ips[0].Equal(net.ParseIP("127.0.0.2"))) - - ah.Close() + assert.NotNil(t, ips) + assert.Equal(t, 1, len(ips)) + assert.Equal(t, "127.0.0.2", ips[0].String()) }