Skip to content
Snippets Groups Projects
change_test.go 5.38 KiB
Newer Older
  • Learn to ignore specific revisions
  • package nucleus
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    import (
    	"context"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"reflect"
    	"sync"
    	"testing"
    	"time"
    
    Andre Sterba's avatar
    Andre Sterba committed
    
    	"github.com/google/uuid"
    	"github.com/openconfig/ygot/exampleoc"
    	"github.com/openconfig/ygot/ygot"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    )
    
    var commit = "commit"
    var rollback = "rollback"
    
    var commitDevice = &exampleoc.Device{
    	System: &exampleoc.System{
    		Hostname: &commit,
    	},
    }
    
    var rollbackDevice = &exampleoc.Device{
    	System: &exampleoc.System{
    		Hostname: &rollback,
    	},
    }
    
    
    func TestChange_CommitRollback(t *testing.T) {
    	wantErr := false
    	want := rollback
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	callback := make(chan string)
    
    	c := &Change{
    
    		cuid:          cuid,
    
    		duid:          did,
    		timestamp:     time.Now(),
    		previousState: rollbackDevice,
    		intendedState: commitDevice,
    		callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
    			hostname := *first.(*exampleoc.Device).System.Hostname
    			t.Logf("hostname: %v", hostname)
    			switch hostname {
    			case rollback:
    				callback <- rollback
    			}
    			return nil
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		},
    
    		lock: sync.RWMutex{},
    	}
    	go func() {
    		time.Sleep(time.Millisecond * 10)
    		if err := c.Commit(); (err != nil) != wantErr {
    			t.Errorf("Commit() error = %v, wantErr %v", err, wantErr)
    		}
    
    		time.Sleep(changeTimeout)
    
    	}()
    	got := <-callback
    	if !reflect.DeepEqual(got, want) {
    		t.Errorf("Commit() = %v, want %v", got, want)
    	}
    	close(callback)
    }
    
    
    func TestChange_CommitRollbackError(t *testing.T) {
    	wantErr := false
    	want := errors.New("this is an expected error")
    	c := &Change{
    
    		cuid:          cuid,
    
    		duid:          did,
    		timestamp:     time.Now(),
    		previousState: rollbackDevice,
    		intendedState: commitDevice,
    		callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
    			hostname := *first.(*exampleoc.Device).System.Hostname
    			t.Logf("hostname: %v", hostname)
    			switch hostname {
    			case rollback:
    				return errors.New("this is an expected error")
    			}
    			return nil
    		},
    		lock:    sync.RWMutex{},
    		errChan: make(chan error),
    	}
    	go func() {
    		time.Sleep(time.Millisecond * 10)
    		if err := c.Commit(); (err != nil) != wantErr {
    			t.Errorf("Commit() error = %v, wantErr %v", err, wantErr)
    		}
    		time.Sleep(changeTimeout)
    	}()
    	got := <-c.errChan
    	if !reflect.DeepEqual(got, want) {
    		t.Errorf("Commit() = %v, want %v", got, want)
    	}
    	close(c.errChan)
    }
    
    func TestChange_CommitError(t *testing.T) {
    	wantErr := true
    	c := &Change{
    
    		cuid:          cuid,
    
    		duid:          did,
    		timestamp:     time.Now(),
    		previousState: rollbackDevice,
    		intendedState: commitDevice,
    		callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
    			return errors.New("this is an expected error")
    		},
    		lock: sync.RWMutex{},
    	}
    	go func() {
    		time.Sleep(time.Millisecond * 10)
    		if err := c.Commit(); (err != nil) != wantErr {
    			t.Errorf("Commit() error = %v, wantErr %v", err, wantErr)
    		}
    	}()
    	got := c.committed
    	if !reflect.DeepEqual(got, false) {
    		t.Errorf("Commit() = %v, want %v", got, false)
    	}
    }
    
    
    func TestChange_Commit(t *testing.T) {
    	wantErr := false
    	want := commit
    	callback := make(chan string)
    
    	c := &Change{
    
    		cuid:          cuid,
    
    		duid:          did,
    		timestamp:     time.Now(),
    		previousState: rollbackDevice,
    		intendedState: commitDevice,
    		callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
    			hostname := *first.(*exampleoc.Device).System.Hostname
    			t.Logf("hostname: %v", hostname)
    			callback <- hostname
    			return nil
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		},
    
    		lock:    sync.RWMutex{},
    		errChan: make(chan error),
    		Done:    make(chan int),
    
    	go func() {
    		time.Sleep(time.Millisecond * 10)
    		if err := c.Commit(); (err != nil) != wantErr {
    			t.Errorf("Commit() error = %v, wantErr %v", err, wantErr)
    		}
    		if err := c.Confirm(); err != nil {
    			t.Errorf("Commit() error = %v", err)
    		}
    	}()
    	got := <-callback
    	if !reflect.DeepEqual(got, want) {
    		t.Errorf("Commit() = %v, want %v", got, want)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	}
    	close(callback)
    }
    
    func TestChange_Confirm(t *testing.T) {
    	_, cancel := context.WithCancel(context.Background())
    	type fields struct {
    		cuid          uuid.UUID
    		duid          uuid.UUID
    		timestamp     time.Time
    		previousState ygot.GoStruct
    		intendedState ygot.GoStruct
    		callback      func(ygot.GoStruct, ygot.GoStruct) error
    		committed     bool
    	}
    	tests := []struct {
    
    		name    string
    		fields  fields
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		wantErr bool
    	}{
    		{
    			name: "committed",
    			fields: fields{
    				committed: true,
    			},
    			wantErr: false,
    		},
    		{
    
    			name:    "uncommitted",
    			fields:  fields{},
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			wantErr: true,
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    			c := &Change{
    
    				committed: tt.fields.committed,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				timestamp: tt.fields.timestamp,
    				previousState: &exampleoc.Device{
    					System: &exampleoc.System{
    						Hostname: &rollback,
    					},
    				},
    				intendedState: &exampleoc.Device{
    					System: &exampleoc.System{
    						Hostname: &commit,
    					},
    				},
    				cancelFunc: cancel,
    				lock:       sync.RWMutex{},
    
    				errChan:    make(chan error),
    				Done:       make(chan int, 1),
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			}
    			if err := c.Confirm(); (err != nil) != tt.wantErr {
    				t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr)
    			}
    		})
    	}
    	cancel()
    }
    
    func TestChange_ID(t *testing.T) {
    	type fields struct {
    		cuid uuid.UUID
    	}
    	tests := []struct {
    		name   string
    		fields fields
    		want   uuid.UUID
    	}{
    		{
    			name:   "default",
    
    			fields: fields{cuid: cuid},
    			want:   cuid,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    			c := &Change{
    				cuid: tt.fields.cuid,
    			}
    			if got := c.ID(); !reflect.DeepEqual(got, tt.want) {
    				t.Errorf("ID() = %v, want %v", got, tt.want)
    			}
    		})
    	}
    }