Skip to content
Snippets Groups Projects
change_test.go 6.73 KiB
Newer Older
  • Learn to ignore specific revisions
  • package nucleus
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    import (
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"reflect"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"testing"
    	"time"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd"
    
    	"code.fbi.h-da.de/danet/gosdn/config"
    
    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 commitHostname = "commit"
    var rollbackHostname = "rollback"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    var commitDevice = &exampleoc.Device{
    	System: &exampleoc.System{
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		Hostname: &commitHostname,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	},
    }
    
    var rollbackDevice = &exampleoc.Device{
    	System: &exampleoc.System{
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		Hostname: &rollbackHostname,
    
    func TestChange_CommitRollback(t *testing.T) {
    
    	wg := sync.WaitGroup{}
    
    	wantErr := false
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	want := rollbackHostname
    
    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("callback in test %v", t.Name())
    
    			switch hostname {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			case rollbackHostname:
    				callback <- rollbackHostname
    
    			}
    			return nil
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		},
    
    	stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
    	c.stateIn = stateIn
    	c.stateOut = stateOut
    	c.requestState = requestState
    	c.errChan = errChan
    	wg.Add(1)
    
    	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(config.ChangeTimeout)
    
    	}()
    	got := <-callback
    	if !reflect.DeepEqual(got, want) {
    		t.Errorf("Commit() = %v, want %v", got, want)
    	}
    
    func TestChange_CommitRollbackError(t *testing.T) {
    
    	wg := sync.WaitGroup{}
    	wg.Add(1)
    
    	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 {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			hostname := *second.(*exampleoc.Device).System.Hostname
    
    			t.Logf("callback in test %v", t.Name())
    
    			switch hostname {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			case rollbackHostname:
    
    				return errors.New("this is an expected error")
    			}
    			return nil
    		},
    	}
    
    	stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
    	c.stateIn = stateIn
    	c.stateOut = stateOut
    	c.requestState = requestState
    	c.errChan = errChan
    
    
    		time.Sleep(time.Millisecond * 10)
    		if err := c.Commit(); (err != nil) != wantErr {
    			t.Errorf("Commit() error = %v, wantErr %v", err, wantErr)
    		}
    
    		time.Sleep(config.ChangeTimeout)
    
    	}()
    	got := <-c.errChan
    	if !reflect.DeepEqual(got, want) {
    		t.Errorf("Commit() = %v, want %v", got, want)
    	}
    
    }
    
    func TestChange_CommitError(t *testing.T) {
    
    	want := ppb.Change_INCONSISTENT
    
    		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")
    		},
    	}
    
    	stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
    	c.stateIn = stateIn
    	c.stateOut = stateOut
    	c.requestState = requestState
    	c.errChan = errChan
    
    	time.Sleep(time.Millisecond * 10)
    	if err := c.Commit(); err == nil {
    		t.Errorf("Commit() expected error, error = %v", err)
    	}
    	got := c.State()
    	if !reflect.DeepEqual(got, want) {
    		t.Errorf("Commit() = %v, want %v", got, want)
    
    func TestChange_Commit(t *testing.T) {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	want := ppb.Change_COMMITTED
    
    	c := &Change{
    
    		cuid:          cuid,
    
    		duid:          did,
    		timestamp:     time.Now(),
    		previousState: rollbackDevice,
    		intendedState: commitDevice,
    		callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
    
    			t.Logf("callback in test %v", t.Name())
    
    			return nil
    
    	stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
    	c.stateIn = stateIn
    	c.stateOut = stateOut
    	c.requestState = requestState
    	c.errChan = errChan
    
    
    	if err := c.Commit(); err != nil {
    		t.Errorf("Commit() error = %v", err)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	}
    	got := c.State()
    
    	if !reflect.DeepEqual(got, want) {
    		t.Errorf("Commit() = %v, want %v", got, want)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	if err := c.Confirm(); err != nil {
    		t.Errorf("Confirm() error = %v", err)
    	}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    }
    
    func TestChange_Confirm(t *testing.T) {
    	tests := []struct {
    
    		name    string
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		wantErr bool
    	}{
    		{
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			name:    "committed",
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			wantErr: false,
    		},
    		{
    
    			name:    "uncommitted",
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			wantErr: true,
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    			c := &Change{
    				previousState: &exampleoc.Device{
    					System: &exampleoc.System{
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    						Hostname: &rollbackHostname,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    					},
    				},
    				intendedState: &exampleoc.Device{
    					System: &exampleoc.System{
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    						Hostname: &commitHostname,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
    
    					t.Logf("callback in test %v", t.Name())
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    					return nil
    				},
    			}
    
    			stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
    			c.stateIn = stateIn
    			c.stateOut = stateOut
    			c.requestState = requestState
    			c.errChan = errChan
    
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			if tt.name == "committed" {
    				if err := c.Commit(); err != nil {
    					t.Errorf("Commit() error = %v, wantErr %v", err, tt.wantErr)
    				}
    
    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)
    			}
    		})
    	}
    }
    
    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)
    			}
    		})
    	}
    }
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    func TestChange_State(t *testing.T) {
    	tests := []struct {
    		name string
    		want ppb.Change_State
    	}{
    		{
    			name: "pending",
    			want: ppb.Change_PENDING,
    		},
    		{
    			name: "committed",
    			want: ppb.Change_COMMITTED,
    		},
    		{
    			name: "confirmed",
    			want: ppb.Change_CONFIRMED,
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    			callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
    
    				t.Logf("callback in test %v", t.Name())
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				return nil
    			}
    
    			c := NewChange(did, rollbackDevice, commitDevice, callback)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			if tt.name != "pending" {
    				if err := c.Commit(); err != nil {
    					t.Errorf("Commit() error = %v", err)
    				}
    			}
    			if tt.name == "confirmed" {
    				if err := c.Confirm(); err != nil {
    					t.Errorf("Confirm() error = %v", err)
    				}
    			}
    			if got := c.State(); !reflect.DeepEqual(got, tt.want) {
    				t.Errorf("Change.State() = %v, want %v", got, tt.want)
    			}
    		})
    	}
    }