...

Source file src/github.com/redhat-developer/odo/pkg/watch/watch_test.go

Documentation: github.com/redhat-developer/odo/pkg/watch

     1  package watch
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"testing"
     8  	"time"
     9  
    10  	"k8s.io/apimachinery/pkg/watch"
    11  
    12  	"github.com/fsnotify/fsnotify"
    13  
    14  	"github.com/redhat-developer/odo/pkg/dev"
    15  	odocontext "github.com/redhat-developer/odo/pkg/odo/context"
    16  )
    17  
    18  func evaluateChangesHandler(events []fsnotify.Event, path string, fileIgnores []string, watcher *fsnotify.Watcher) ([]string, []string) {
    19  	var changedFiles []string
    20  	var deletedPaths []string
    21  
    22  	for _, event := range events {
    23  		for _, file := range fileIgnores {
    24  			// if file is in fileIgnores, don't do anything
    25  			if event.Name == file {
    26  				continue
    27  			}
    28  		}
    29  		// this if condition is copied from original implementation in watch.go. Code within the if block is simplified for tests
    30  		if event.Op&fsnotify.Remove == fsnotify.Remove || event.Op&fsnotify.Rename == fsnotify.Rename {
    31  			// On remove/rename, stop watching the resource
    32  			_ = watcher.Remove(event.Name)
    33  			// Append the file to list of deleted files
    34  			deletedPaths = append(deletedPaths, event.Name)
    35  			continue
    36  		}
    37  		// this if condition is copied from original implementation in watch.go. Code within the if block is simplified for tests
    38  		if event.Op&fsnotify.Remove != fsnotify.Remove {
    39  			changedFiles = append(changedFiles, event.Name)
    40  		}
    41  	}
    42  	return changedFiles, deletedPaths
    43  }
    44  
    45  func processEventsHandler(ctx context.Context, params WatchParameters, changedFiles, deletedPaths []string, componentStatus *ComponentStatus) error {
    46  	fmt.Fprintf(params.StartOptions.Out, "changedFiles %s deletedPaths %s\n", changedFiles, deletedPaths)
    47  	return nil
    48  }
    49  
    50  type fakeWatcher struct{}
    51  
    52  func (o fakeWatcher) Stop() {
    53  }
    54  
    55  func (o fakeWatcher) ResultChan() <-chan watch.Event {
    56  	return make(chan watch.Event, 1)
    57  }
    58  
    59  func Test_eventWatcher(t *testing.T) {
    60  	type args struct {
    61  		parameters WatchParameters
    62  	}
    63  	tests := []struct {
    64  		name          string
    65  		args          args
    66  		wantOut       string
    67  		wantErr       bool
    68  		watcherEvents []fsnotify.Event
    69  		watcherError  error
    70  	}{
    71  		{
    72  			name: "Case 1: Multiple events, no errors",
    73  			args: args{
    74  				parameters: WatchParameters{},
    75  			},
    76  			wantOut:       "Pushing files...\n\nchangedFiles [file1 file2] deletedPaths []\n",
    77  			wantErr:       false,
    78  			watcherEvents: []fsnotify.Event{{Name: "file1", Op: fsnotify.Create}, {Name: "file2", Op: fsnotify.Write}},
    79  			watcherError:  nil,
    80  		},
    81  		{
    82  			name: "Case 2: Multiple events, one error",
    83  			args: args{
    84  				parameters: WatchParameters{},
    85  			},
    86  			wantOut:       "",
    87  			wantErr:       true,
    88  			watcherEvents: []fsnotify.Event{{Name: "file1", Op: fsnotify.Create}, {Name: "file2", Op: fsnotify.Write}},
    89  			watcherError:  fmt.Errorf("error"),
    90  		},
    91  		{
    92  			name: "Case 3: Delete file, no error",
    93  			args: args{
    94  				parameters: WatchParameters{
    95  					StartOptions: dev.StartOptions{
    96  						IgnorePaths: []string{"file1"},
    97  					},
    98  				},
    99  			},
   100  			wantOut:       "Pushing files...\n\nchangedFiles [] deletedPaths [file1 file2]\n",
   101  			wantErr:       false,
   102  			watcherEvents: []fsnotify.Event{{Name: "file1", Op: fsnotify.Remove}, {Name: "file2", Op: fsnotify.Rename}},
   103  			watcherError:  nil,
   104  		},
   105  		{
   106  			name: "Case 4: Only errors",
   107  			args: args{
   108  				parameters: WatchParameters{},
   109  			},
   110  			wantOut:       "",
   111  			wantErr:       true,
   112  			watcherEvents: nil,
   113  			watcherError:  fmt.Errorf("error1"),
   114  		},
   115  	}
   116  	for _, tt := range tests {
   117  		t.Run(tt.name, func(t *testing.T) {
   118  			watcher, _ := fsnotify.NewWatcher()
   119  			fileWatcher, _ := fsnotify.NewWatcher()
   120  			var cancel context.CancelFunc
   121  			ctx, cancel := context.WithCancel(context.Background())
   122  			ctx = odocontext.WithDevfilePath(ctx, "/path/to/devfile")
   123  			ctx = odocontext.WithApplication(ctx, "odo")
   124  			ctx = odocontext.WithComponentName(ctx, "my-component")
   125  			out := &bytes.Buffer{}
   126  
   127  			go func() {
   128  				for _, event := range tt.watcherEvents {
   129  					watcher.Events <- event
   130  				}
   131  
   132  				if tt.watcherError != nil {
   133  					watcher.Errors <- tt.watcherError
   134  				}
   135  				<-time.After(500 * time.Millisecond)
   136  				cancel()
   137  			}()
   138  
   139  			componentStatus := ComponentStatus{}
   140  			componentStatus.SetState(StateReady)
   141  
   142  			o := WatchClient{
   143  				sourcesWatcher:    watcher,
   144  				deploymentWatcher: fakeWatcher{},
   145  				podWatcher:        fakeWatcher{},
   146  				warningsWatcher:   fakeWatcher{},
   147  				devfileWatcher:    fileWatcher,
   148  				keyWatcher:        make(chan byte),
   149  			}
   150  			tt.args.parameters.StartOptions.Out = out
   151  
   152  			err := o.eventWatcher(ctx, tt.args.parameters, evaluateChangesHandler, processEventsHandler, componentStatus)
   153  			if (err != nil) != tt.wantErr {
   154  				t.Errorf("eventWatcher() error = %v, wantErr %v", err, tt.wantErr)
   155  				return
   156  			}
   157  
   158  			if gotOut := out.String(); gotOut != tt.wantOut {
   159  				t.Errorf("eventWatcher() gotOut = %v, want %v", gotOut, tt.wantOut)
   160  			}
   161  		})
   162  	}
   163  }
   164  

View as plain text