github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/exp/inotify/inotify_linux_test.go (about)

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build linux
     6  
     7  package inotify
     8  
     9  import (
    10  	"io/ioutil"
    11  	"os"
    12  	"sync/atomic"
    13  	"testing"
    14  	"time"
    15  )
    16  
    17  func TestInotifyEvents(t *testing.T) {
    18  	// Create an inotify watcher instance and initialize it
    19  	watcher, err := NewWatcher()
    20  	if err != nil {
    21  		t.Fatalf("NewWatcher failed: %s", err)
    22  	}
    23  
    24  	dir, err := ioutil.TempDir("", "inotify")
    25  	if err != nil {
    26  		t.Fatalf("TempDir failed: %s", err)
    27  	}
    28  	defer os.RemoveAll(dir)
    29  
    30  	// Add a watch for "_test"
    31  	err = watcher.Watch(dir)
    32  	if err != nil {
    33  		t.Fatalf("Watch failed: %s", err)
    34  	}
    35  
    36  	// Receive errors on the error channel on a separate goroutine
    37  	go func() {
    38  		for err := range watcher.Error {
    39  			t.Fatalf("error received: %s", err)
    40  		}
    41  	}()
    42  
    43  	testFile := dir + "/TestInotifyEvents.testfile"
    44  
    45  	// Receive events on the event channel on a separate goroutine
    46  	eventstream := watcher.Event
    47  	var eventsReceived int32 = 0
    48  	done := make(chan bool)
    49  	go func() {
    50  		for event := range eventstream {
    51  			// Only count relevant events
    52  			if event.Name == testFile {
    53  				atomic.AddInt32(&eventsReceived, 1)
    54  				t.Logf("event received: %s", event)
    55  			} else {
    56  				t.Logf("unexpected event received: %s", event)
    57  			}
    58  		}
    59  		done <- true
    60  	}()
    61  
    62  	// Create a file
    63  	// This should add at least one event to the inotify event queue
    64  	_, err = os.OpenFile(testFile, os.O_WRONLY|os.O_CREATE, 0666)
    65  	if err != nil {
    66  		t.Fatalf("creating test file: %s", err)
    67  	}
    68  
    69  	// We expect this event to be received almost immediately, but let's wait 1 s to be sure
    70  	time.Sleep(1 * time.Second)
    71  	if atomic.AddInt32(&eventsReceived, 0) == 0 {
    72  		t.Fatal("inotify event hasn't been received after 1 second")
    73  	}
    74  
    75  	// Try closing the inotify instance
    76  	t.Log("calling Close()")
    77  	watcher.Close()
    78  	t.Log("waiting for the event channel to become closed...")
    79  	select {
    80  	case <-done:
    81  		t.Log("event channel closed")
    82  	case <-time.After(1 * time.Second):
    83  		t.Fatal("event stream was not closed after 1 second")
    84  	}
    85  }
    86  
    87  func TestInotifyClose(t *testing.T) {
    88  	watcher, _ := NewWatcher()
    89  	watcher.Close()
    90  
    91  	done := make(chan bool)
    92  	go func() {
    93  		watcher.Close()
    94  		done <- true
    95  	}()
    96  
    97  	select {
    98  	case <-done:
    99  	case <-time.After(50 * time.Millisecond):
   100  		t.Fatal("double Close() test failed: second Close() call didn't return")
   101  	}
   102  
   103  	err := watcher.Watch(os.TempDir())
   104  	if err == nil {
   105  		t.Fatal("expected error on Watch() after Close(), got nil")
   106  	}
   107  }