github.com/contiv/libOpenflow@v0.0.0-20210609050114-d967b14cc688/openflow13/nxext_test.go (about)

     1  package openflow13
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"encoding/hex"
     7  	"errors"
     8  	"fmt"
     9  	"net"
    10  	"testing"
    11  )
    12  
    13  func TestNXActionResubmit(t *testing.T) {
    14  	tableID := uint8(10)
    15  	portID := uint16(10)
    16  
    17  	action1 := NewNXActionResubmit(portID)
    18  	data1, err := action1.MarshalBinary()
    19  	if err != nil {
    20  		t.Fatalf("Failed to invoke NXAST_RESUBMIT.MarshalBinary: %v", err)
    21  	}
    22  	testAction1 := new(NXActionResubmitTable)
    23  	testAction1.UnmarshalBinary(data1)
    24  	if testAction1.InPort != portID {
    25  		t.Errorf("Failed to invoke NXAST_RESUBMIT.UnmarshalBinary, expect: %x, actual: %x", portID, testAction1.InPort)
    26  	}
    27  
    28  	action2 := NewNXActionResubmitTableAction(portID, tableID)
    29  	if action2.Length != 16 {
    30  		t.Errorf("Failed to create action2 NXAST_RESUBMIT_TABLE")
    31  	}
    32  	data2, err := action2.MarshalBinary()
    33  	if err != nil {
    34  		t.Fatalf("Failed to invoke NXAST_RESUBMIT_TABLE.MarshalBinary: %v", err)
    35  	}
    36  	testAction2 := newNXActionResubmitTable()
    37  	testAction2.UnmarshalBinary(data2)
    38  	if testAction2.TableID != tableID {
    39  		t.Errorf("Failed to invoke NXAST_RESUBMIT_TABLE.UnmarshalBinary, expect: %x, actual: %x", tableID, testAction2.TableID)
    40  	}
    41  	if testAction2.InPort != portID {
    42  		t.Errorf("Failed to invoke NXAST_RESUBMIT_TABLE.UnmarshalBinary, expect: %x, actual: %x", portID, testAction2.InPort)
    43  	}
    44  
    45  	action3 := NewNXActionResubmitTableAction(OFPP_IN_PORT, tableID)
    46  	if action3.Length != 16 {
    47  		t.Errorf("Failed to create action2 NXAST_RESUBMIT_TABLE")
    48  	}
    49  	data3, err := action3.MarshalBinary()
    50  	if err != nil {
    51  		t.Fatalf("Failed to invoke NXAST_RESUBMIT_TABLE.MarshalBinary: %v", err)
    52  	}
    53  	testAction3 := newNXActionResubmitTable()
    54  	testAction3.UnmarshalBinary(data3)
    55  	if testAction3.TableID != tableID {
    56  		t.Errorf("Failed to invoke NXAST_RESUBMIT_TABLE.UnmarshalBinary, expect: %x, actual: %x", tableID, testAction3.TableID)
    57  	}
    58  	if testAction3.InPort != OFPP_IN_PORT {
    59  		t.Errorf("Failed to invoke NXAST_RESUBMIT_TABLE.UnmarshalBinary, expect: %x, actual: %x", portID, testAction3.InPort)
    60  	}
    61  
    62  	action4 := NewNXActionResubmitTableCT(portID, tableID)
    63  	data4, err := action4.MarshalBinary()
    64  	if err != nil {
    65  		t.Fatalf("Failed to invoke NXAST_RESUBMIT_TABLE.MarshalBinary: %v", err)
    66  	}
    67  	testAction4 := newNXActionResubmitTableCT()
    68  	testAction4.UnmarshalBinary(data4)
    69  	if !testAction4.IsCT() {
    70  		t.Error("Failed to invoke NXAST_RESUBMIT_TABLE.MarshalBinary")
    71  	}
    72  	if testAction4.TableID != tableID {
    73  		t.Errorf("Failed to invoke NXAST_RESUBMIT_TABLE_CT.UnmarshalBinary, expect: %x, actual: %x", tableID, testAction4.TableID)
    74  	}
    75  	if testAction4.InPort != portID {
    76  		t.Errorf("Failed to invoke NXAST_RESUBMIT_TABLE_CT.UnmarshalBinary, expect: %x, actual: %x", portID, testAction4.InPort)
    77  	}
    78  
    79  	action5 := NewNXActionResubmitTableCTNoInPort(tableID)
    80  	data5, err := action5.MarshalBinary()
    81  	if err != nil {
    82  		t.Fatalf("Failed to invoke NXAST_RESUBMIT_TABLE.MarshalBinary: %v", err)
    83  	}
    84  	testAction5 := newNXActionResubmitTableCT()
    85  	if !testAction5.IsCT() {
    86  		t.Error("Failed to invoke NXAST_CT_RESUBMIT.MarshalBinary")
    87  	}
    88  	testAction5.UnmarshalBinary(data5)
    89  	if testAction5.TableID != tableID {
    90  		t.Errorf("Failed to invoke NXAST_CT_RESUBMIT.UnmarshalBinary, expect: %x, actual: %x", tableID, testAction5.TableID)
    91  	}
    92  	if testAction5.InPort != OFPP_IN_PORT {
    93  		t.Errorf("Failed to invoke NXAST_CT_RESUBMIT.UnmarshalBinary, expect: %x, actual: %x", portID, testAction5.InPort)
    94  	}
    95  }
    96  
    97  func TestNOfs(t *testing.T) {
    98  	var start, ofs, end, nBits uint16
    99  	start = uint16(16)
   100  	ofs = uint16(16)
   101  	nBits = uint16(16)
   102  	end = uint16(31)
   103  
   104  	encodeStartEnd := encodeOfsNbitsStartEnd(start, end)
   105  	encodeOfsNbits := encodeOfsNbits(ofs, nBits)
   106  	decodeOfs := decodeOfs(encodeOfsNbits)
   107  	deCodeNbits := decodeNbits(encodeOfsNbits)
   108  
   109  	if encodeStartEnd != encodeOfsNbits {
   110  		t.Errorf("Failed to encode from start to end, expect: %d, actual: %d", encodeOfsNbits, encodeStartEnd)
   111  	}
   112  	if ofs != decodeOfs {
   113  		t.Errorf("Failed to decode ofs, expect: %d, actual: %d", ofs, decodeOfs)
   114  	}
   115  	if nBits != deCodeNbits {
   116  		t.Errorf("Failed to decode nBits, expect: %d, actual: %d", nBits, deCodeNbits)
   117  	}
   118  }
   119  
   120  func TestUint32Message(t *testing.T) {
   121  	tgtData := uint32(0xff00ff00)
   122  	msg := newUint32Message(tgtData)
   123  	if msg.Len() != 4 {
   124  		t.Errorf("Failed to generate Uint32Message")
   125  	}
   126  	testData, err := msg.MarshalBinary()
   127  	if err != nil {
   128  		t.Errorf("Failed to invoke Uint32Message.MarshalBinary, %v", err)
   129  	}
   130  	var testMsg = new(Uint32Message)
   131  	err = testMsg.UnmarshalBinary(testData)
   132  	if err != nil {
   133  		t.Errorf("Failed to invoke Uint32Message.UnmarshalBinary, %v", err)
   134  	}
   135  	if testMsg.Data != tgtData {
   136  		t.Errorf("Failed to retrieve uint32 from Uint32Message, tgt: %d, actual: %d", tgtData, testMsg.Data)
   137  	}
   138  }
   139  
   140  func TestUint16Message(t *testing.T) {
   141  	tgtData := uint16(0xfe10)
   142  	msg := newUint16Message(tgtData)
   143  	if msg.Len() != 2 {
   144  		t.Errorf("Failed to generate Uint32Message")
   145  	}
   146  	testData, err := msg.MarshalBinary()
   147  	if err != nil {
   148  		t.Errorf("Failed to invoke Uint32Message.MarshalBinary, %v", err)
   149  	}
   150  	var testMsg = new(Uint16Message)
   151  	err = testMsg.UnmarshalBinary(testData)
   152  	if err != nil {
   153  		t.Errorf("Failed to invoke Uint32Message.UnmarshalBinary, %v", err)
   154  	}
   155  	if testMsg.Data != tgtData {
   156  		t.Errorf("Failed to retrieve uint32 from Uint32Message, tgt: %d, actual: %d", tgtData, testMsg.Data)
   157  	}
   158  }
   159  
   160  func TestNewUintXMask(t *testing.T) {
   161  	tgtData32 := uint32(0xff)
   162  	rng1 := &NXRange{start: 0, end: 7}
   163  	testMsg := &Uint32Message{Data: rng1.ToUint32Mask()}
   164  	if testMsg.Data != tgtData32 {
   165  		t.Errorf("Failed to invoke newUint32Mask, expected: %02x, actual: %02x", tgtData32, testMsg.Data)
   166  	}
   167  }
   168  
   169  func TestNXMFieldHeader(t *testing.T) {
   170  	for k := range oxxFieldHeaderMap {
   171  		field1, err := FindFieldHeaderByName(k, false)
   172  		if err != nil {
   173  			t.Errorf("Test failed: %v", err)
   174  		}
   175  		testMatchFieldHeaderMarshalUnMarshal(field1, t)
   176  		field2, _ := FindFieldHeaderByName(k, true)
   177  		testMatchFieldHeaderMarshalUnMarshal(field2, t)
   178  	}
   179  }
   180  
   181  func TestCTLabel(t *testing.T) {
   182  	var label = [16]byte{}
   183  	testData, err := hex.DecodeString(fmt.Sprintf("%d", 0x12345678))
   184  	copy(label[:], testData)
   185  	field := newCTLabel(label)
   186  	data, err := field.MarshalBinary()
   187  	if err != nil {
   188  		t.Errorf("Failed to MarshalBinary CTLabel: %v", err)
   189  	}
   190  	field2 := new(CTLabel)
   191  	err = field2.UnmarshalBinary(data)
   192  	if err != nil {
   193  		t.Errorf("Failed to UnmarshalBinary message: %v", err)
   194  	}
   195  	if field2.data != label {
   196  		t.Errorf("Unmarshalled CTLabel is incorrect, expect: %d, actual: %d", label, field2.data)
   197  	}
   198  
   199  	var mask = [16]byte{}
   200  	binary.BigEndian.PutUint32(mask[:], 0xffffffff)
   201  }
   202  
   203  func TestNXActionCTNAT(t *testing.T) {
   204  	act := NewNXActionCTNAT()
   205  	if err := act.SetSNAT(); err != nil {
   206  		t.Errorf("Failed to set SNAT action: %v", err)
   207  	}
   208  	if err := act.SetRandom(); err != nil {
   209  		t.Errorf("Failed to set random action: %v", err)
   210  	}
   211  	ipMin := net.ParseIP("10.0.0.200")
   212  	ipMax := net.ParseIP("10.0.0.240")
   213  	act.SetRangeIPv4Min(ipMin)
   214  	act.SetRangeIPv4Max(ipMax)
   215  	minPort := uint16(2048)
   216  	maxPort := uint16(10240)
   217  	act.SetRangeProtoMin(&minPort)
   218  	act.SetRangeProtoMax(&maxPort)
   219  	data, err := act.MarshalBinary()
   220  	if err != nil {
   221  		t.Errorf("Failed to Marshal NXActionCTNAT: %v", err)
   222  	}
   223  	act2 := new(NXActionCTNAT)
   224  	err = act2.UnmarshalBinary(data)
   225  	if err != nil {
   226  		t.Errorf("Failed to Unmarshal NXActionCTNAT: %v", err)
   227  	}
   228  	if act2.rangeIPv4Min.String() != ipMin.String() {
   229  		t.Errorf("Failed to set RangeIPv4Min, expect: %s, actual: %s", ipMin.String(), act2.rangeIPv4Min.String())
   230  	}
   231  	if act2.rangeIPv4Max.String() != ipMax.String() {
   232  		t.Errorf("Failed to set rangeIPv4Max, expect: %s, actual: %s", ipMax.String(), act2.rangeIPv4Max.String())
   233  	}
   234  	if *act2.rangeProtoMin != minPort {
   235  		t.Errorf("Failed to set SetRangeProtoMin, expect: %d, actual: %d", minPort, *act2.rangeProtoMin)
   236  	}
   237  	if *act2.rangeProtoMax != maxPort {
   238  		t.Errorf("Failed to set SetRangeProtoMax, expect: %d, actual: %d", maxPort, *act2.rangeProtoMax)
   239  	}
   240  }
   241  
   242  func TestNXActions(t *testing.T) {
   243  	translateMessages(t, NewNXActionConjunction(uint8(1), uint8(3), uint32(0xffee)), new(NXActionConjunction), nxConjunctionEquals)
   244  
   245  	dstField, _ := FindFieldHeaderByName("NXM_NX_REG0", false)
   246  	loadData := uint64(0xf009)
   247  	translateMessages(t, NewNXActionRegLoad(NewNXRange(0, 31).ToOfsBits(), dstField, loadData), new(NXActionRegLoad), nxRegLoadEquals)
   248  
   249  	moveSrc, _ := FindFieldHeaderByName("NXM_OF_ETH_SRC", false)
   250  	moveDst, _ := FindFieldHeaderByName("NXM_OF_ETH_DST", false)
   251  	translateMessages(t, NewNXActionRegMove(48, 0, 0, moveSrc, moveDst), new(NXActionRegMove), nxRegMoveEquals)
   252  
   253  	outputFiled, _ := FindFieldHeaderByName("NXM_NX_REG1", false)
   254  	translateMessages(t, NewOutputFromField(outputFiled, NewNXRange(0, 31).ToOfsBits()), new(NXActionOutputReg), nxOutputRegEquals)
   255  	translateMessages(t, NewOutputFromFieldWithMaxLen(outputFiled, NewNXRange(0, 31).ToOfsBits(), uint16(0xfffe)), new(NXActionOutputReg), nxOutputRegEquals)
   256  
   257  	translateMessages(t, NewNXActionDecTTL(), new(NXActionDecTTL), nxDecTTLEquals)
   258  	translateMessages(t, NewNXActionDecTTLCntIDs(2, uint16(1), uint16(2)), new(NXActionDecTTLCntIDs), nxDecTTLCntIDsEquals)
   259  
   260  }
   261  
   262  func TestNXActionNote(t *testing.T) {
   263  	note := []byte("test-notes")
   264  	oriAction := &NXActionNote{
   265  		NXActionHeader: NewNxActionHeader(NXAST_NOTE),
   266  		Note:           note,
   267  	}
   268  	data, err := oriAction.MarshalBinary()
   269  	if err != nil {
   270  		t.Fatalf("Failed to Marshal message: %v", err)
   271  	}
   272  	newAction := &NXActionNote{}
   273  	err = newAction.UnmarshalBinary(data)
   274  	if err != nil {
   275  		t.Fatalf("Failed to UnMarshal message: %v", err)
   276  	}
   277  	oriNoteLength := len(oriAction.Note)
   278  	newNoteLength := len(newAction.Note)
   279  	if newNoteLength < oriNoteLength {
   280  		t.Errorf("Failed to read all note data")
   281  	}
   282  	if !bytes.Equal(oriAction.Note, newAction.Note[:oriNoteLength]) {
   283  		t.Errorf("note not equal")
   284  	}
   285  }
   286  
   287  func TestNXLearnSpecHeader(t *testing.T) {
   288  	testFunc := func(oriHeader *NXLearnSpecHeader) {
   289  		data, err := oriHeader.MarshalBinary()
   290  		if err != nil {
   291  			t.Fatalf("Failed to Marshal message: %v", err)
   292  		}
   293  		newHeader := &NXLearnSpecHeader{}
   294  		err = newHeader.UnmarshalBinary(data)
   295  		if err != nil {
   296  			t.Fatalf("Failed to UnMarshal message: %v", err)
   297  		}
   298  		if err = nxLearnSpecHeaderEquals(oriHeader, newHeader); err != nil {
   299  			t.Error(err)
   300  		}
   301  	}
   302  	nBits := uint16(48)
   303  	for _, f := range []func(n uint16) *NXLearnSpecHeader{
   304  		NewLearnHeaderMatchFromValue,
   305  		NewLearnHeaderMatchFromField,
   306  		NewLearnHeaderLoadFromValue,
   307  		NewLearnHeaderLoadFromField,
   308  		NewLearnHeaderOutputFromField,
   309  	} {
   310  		testFunc(f(nBits))
   311  	}
   312  }
   313  
   314  func TestNXLearnSpec(t *testing.T) {
   315  	testFunc := func(oriSpec *NXLearnSpec) {
   316  		data, err := oriSpec.MarshalBinary()
   317  		if err != nil {
   318  			t.Fatalf("Failed to Marshal message: %v", err)
   319  		}
   320  		newSpec := new(NXLearnSpec)
   321  		err = newSpec.UnmarshalBinary(data)
   322  		if err != nil {
   323  			t.Fatalf("Failed to UnMarshal message: %v", err)
   324  		}
   325  		if err = nxLearnSpecEquals(oriSpec, newSpec); err != nil {
   326  			t.Error(err)
   327  		}
   328  	}
   329  
   330  	for _, spec := range prepareLearnSpecs() {
   331  		testFunc(spec)
   332  	}
   333  }
   334  
   335  func TestNXActionLearn(t *testing.T) {
   336  	testFunc := func(oriAction *NXActionLearn) {
   337  		data, err := oriAction.MarshalBinary()
   338  		if err != nil {
   339  			t.Fatalf("Failed to Marshal message: %v", err)
   340  		}
   341  		newAction := new(NXActionLearn)
   342  		err = newAction.UnmarshalBinary(data)
   343  		if err != nil {
   344  			t.Fatalf("Failed to UnMarshal message: %v", err)
   345  		}
   346  		if err = nsLearnEquals(oriAction, newAction); err != nil {
   347  			t.Error(err)
   348  		}
   349  	}
   350  
   351  	action := &NXActionLearn{
   352  		NXActionHeader: NewNxActionHeader(NXAST_LEARN),
   353  		IdleTimeout:    10,
   354  		HardTimeout:    20,
   355  		Priority:       80,
   356  		Cookie:         0x123456789abcdef0,
   357  		TableID:        2,
   358  		FinIdleTimeout: 2,
   359  		FinHardTimeout: 4,
   360  		LearnSpecs:     prepareLearnSpecs(),
   361  	}
   362  	testFunc(action)
   363  }
   364  
   365  func TestNewNXActionRegLoad2(t *testing.T) {
   366  	testFunc := func(oriAction *NXActionRegLoad2) {
   367  		data, err := oriAction.MarshalBinary()
   368  		if err != nil {
   369  			t.Fatalf("Failed to Marshal message: %v", err)
   370  		}
   371  		newAction := new(NXActionRegLoad2)
   372  		err = newAction.UnmarshalBinary(data)
   373  		if err != nil {
   374  			t.Fatalf("Failed to UnMarshal message: %v", err)
   375  		}
   376  		oriField := oriAction.DstField
   377  		newField := newAction.DstField
   378  		if oriField.Class != newField.Class {
   379  			t.Error("MatchField class not equal")
   380  		}
   381  		if oriField.Field != newField.Field {
   382  			t.Error("MatchField field not equal")
   383  		}
   384  		if oriField.Length != newField.Length {
   385  			t.Error("MatchField length not equal")
   386  		}
   387  		if oriField.HasMask != newField.HasMask {
   388  			t.Error("MatchFiedl mask not equal")
   389  		}
   390  		oriData, _ := oriField.Value.MarshalBinary()
   391  		newData, err := newField.Value.MarshalBinary()
   392  		if err != nil {
   393  			t.Errorf("Failed to Marshal MatchField value: %v", err)
   394  		}
   395  		if !bytes.Equal(oriData, newData) {
   396  			t.Error("Field data not equal")
   397  		}
   398  	}
   399  
   400  	dstField, _ := FindFieldHeaderByName("NXM_NX_CT_MARK", false)
   401  	dstField.Value = newUint32Message(uint32(0x1234))
   402  	load2 := NewNXActionRegLoad2(dstField)
   403  	testFunc(load2)
   404  }
   405  
   406  func TestNXActionController(t *testing.T) {
   407  	testFunc := func(oriAction *NXActionController) {
   408  		data, err := oriAction.MarshalBinary()
   409  		if err != nil {
   410  			t.Fatalf("Failed to Marshal message: %v", err)
   411  		}
   412  		newAction := new(NXActionController)
   413  		err = newAction.UnmarshalBinary(data)
   414  		if err != nil {
   415  			t.Fatalf("Failed to UnMarshal message: %v", err)
   416  		}
   417  		if oriAction.ControllerID != newAction.ControllerID {
   418  			t.Error("ControllerID not equal")
   419  		}
   420  		if oriAction.MaxLen != newAction.MaxLen {
   421  			t.Error("MaxLen not equal")
   422  		}
   423  		if oriAction.Reason != newAction.Reason {
   424  			t.Error("Reason not equal")
   425  		}
   426  	}
   427  
   428  	nxController := NewNXActionController(uint16(1001))
   429  	nxController.Reason = uint8(0)
   430  	nxController.MaxLen = uint16(128)
   431  	testFunc(nxController)
   432  }
   433  
   434  func TestSetControllerID(t *testing.T) {
   435  	testFunc := func(oriMessage *VendorHeader) {
   436  		data, err := oriMessage.MarshalBinary()
   437  		if err != nil {
   438  			t.Fatalf("Failed to Marshal message: %v", err)
   439  		}
   440  		newMessage := new(VendorHeader)
   441  		err = newMessage.UnmarshalBinary(data)
   442  		if err != nil {
   443  			t.Fatalf("Failed to UnMarshal message: %v", err)
   444  		}
   445  		newControllerID, ok := newMessage.VendorData.(*ControllerID)
   446  		if !ok {
   447  			t.Fatalf("Failed to cast ControllerID from result")
   448  		}
   449  		oriControllerID, _ := oriMessage.VendorData.(*ControllerID)
   450  		if newControllerID.ID != oriControllerID.ID {
   451  			t.Error("Controller ID not equal")
   452  		}
   453  	}
   454  
   455  	controllerID := uint16(102)
   456  	message := NewSetControllerID(controllerID)
   457  	testFunc(message)
   458  }
   459  
   460  func TestTLVTableMap(t *testing.T) {
   461  	testFunc := func(oriMessage *TLVTableMap) {
   462  		data, err := oriMessage.MarshalBinary()
   463  		if err != nil {
   464  			t.Fatalf("Failed to Marshal message: %v", err)
   465  		}
   466  		newMesage := new(TLVTableMap)
   467  		err = newMesage.UnmarshalBinary(data)
   468  		if err != nil {
   469  			t.Fatalf("Failed to UnMarshal message: %v", err)
   470  		}
   471  		if err = tlvMapEquals(oriMessage, newMesage); err != nil {
   472  			t.Error(err.Error())
   473  		}
   474  	}
   475  
   476  	tlvMap := &TLVTableMap{
   477  		OptClass:  0xffff,
   478  		OptType:   0,
   479  		OptLength: 16,
   480  		Index:     0,
   481  	}
   482  	testFunc(tlvMap)
   483  }
   484  
   485  func TestTLVTableMod(t *testing.T) {
   486  	testFunc := func(oriMessage *TLVTableMod) {
   487  		data, err := oriMessage.MarshalBinary()
   488  		if err != nil {
   489  			t.Fatalf("Failed to Marshal message: %v", err)
   490  		}
   491  		newMessage := new(TLVTableMod)
   492  		err = newMessage.UnmarshalBinary(data)
   493  		if err != nil {
   494  			t.Fatalf("Failed to UnMarshal message: %v", err)
   495  		}
   496  		if err = tlvMapModEqual(oriMessage, newMessage); err != nil {
   497  			t.Error(err.Error())
   498  		}
   499  	}
   500  
   501  	tlvMod := prepareTLVTableMod()
   502  	testFunc(tlvMod)
   503  }
   504  
   505  func TestTLTableModMessage(t *testing.T) {
   506  	testFunc := func(oriMessage *VendorHeader) {
   507  		data, err := oriMessage.MarshalBinary()
   508  		if err != nil {
   509  			t.Fatalf("Failed to Marshal message: %v", err)
   510  		}
   511  		newMessage := new(VendorHeader)
   512  		err = newMessage.UnmarshalBinary(data)
   513  		if err != nil {
   514  			t.Fatalf("Failed to UnMarshal message: %v", err)
   515  		}
   516  		oriTLVMod := oriMessage.VendorData.(*TLVTableMod)
   517  		newTLVMod, ok := newMessage.VendorData.(*TLVTableMod)
   518  		if !ok {
   519  			t.Fatalf("Failed to cast TLVTableMod from result")
   520  		}
   521  		if err = tlvMapModEqual(oriTLVMod, newTLVMod); err != nil {
   522  			t.Error(err.Error())
   523  		}
   524  	}
   525  
   526  	tlvModMessage := NewTLVTableModMessage(prepareTLVTableMod())
   527  	testFunc(tlvModMessage)
   528  }
   529  
   530  func TestTLVTableReply(t *testing.T) {
   531  	testFunc := func(oriMessage *TLVTableReply) {
   532  		data, err := oriMessage.MarshalBinary()
   533  		if err != nil {
   534  			t.Fatalf("Failed to Marshal message: %v", err)
   535  		}
   536  		newMessage := new(TLVTableReply)
   537  		err = newMessage.UnmarshalBinary(data)
   538  		if err != nil {
   539  			t.Fatalf("Failed to UnMarshal message: %v", err)
   540  		}
   541  		if err = tlvTableReplyEqual(oriMessage, newMessage); err != nil {
   542  			t.Error(err)
   543  		}
   544  	}
   545  
   546  	reply := &TLVTableReply{
   547  		MaxSpace:  248,
   548  		MaxFields: 62,
   549  		TlvMaps:   prepareTLVTableMaps(),
   550  	}
   551  	testFunc(reply)
   552  }
   553  
   554  func TestTLVTableReplyMessage(t *testing.T) {
   555  	testFunc := func(oriMessage *VendorHeader) {
   556  		data, err := oriMessage.MarshalBinary()
   557  		if err != nil {
   558  			t.Fatalf("Failed to Marshal message: %v", err)
   559  		}
   560  		newMessage := new(VendorHeader)
   561  		err = newMessage.UnmarshalBinary(data)
   562  		if err != nil {
   563  			t.Fatalf("Failed to UnMarshal message: %v", err)
   564  		}
   565  		oriTLVReply := oriMessage.VendorData.(*TLVTableReply)
   566  		newTLVReply, ok := newMessage.VendorData.(*TLVTableReply)
   567  		if !ok {
   568  			t.Fatalf("Failed to cast TLVTableReply from result")
   569  		}
   570  		if err = tlvTableReplyEqual(oriTLVReply, newTLVReply); err != nil {
   571  			t.Error(err.Error())
   572  		}
   573  	}
   574  
   575  	reply := &TLVTableReply{
   576  		MaxSpace:  248,
   577  		MaxFields: 62,
   578  		TlvMaps:   prepareTLVTableMaps(),
   579  	}
   580  	tlvReplyMessage := NewNXTVendorHeader(Type_TlvTableReply)
   581  	tlvReplyMessage.VendorData = reply
   582  	testFunc(tlvReplyMessage)
   583  }
   584  
   585  func tlvTableReplyEqual(oriMessage, newMessage *TLVTableReply) error {
   586  	if oriMessage.MaxSpace != newMessage.MaxSpace {
   587  		return errors.New("Max space not equal")
   588  	}
   589  	if oriMessage.MaxFields != newMessage.MaxFields {
   590  		return errors.New("Max field not equal")
   591  	}
   592  	for i := range oriMessage.TlvMaps {
   593  		if err := tlvMapEquals(oriMessage.TlvMaps[i], newMessage.TlvMaps[i]); err != nil {
   594  			return err
   595  		}
   596  	}
   597  	return nil
   598  }
   599  
   600  func tlvMapModEqual(oriMessage *TLVTableMod, newMessage *TLVTableMod) error {
   601  	if oriMessage.Command != newMessage.Command {
   602  		return errors.New("message command not equal")
   603  	}
   604  	for i := range oriMessage.TlvMaps {
   605  		if err := tlvMapEquals(oriMessage.TlvMaps[i], newMessage.TlvMaps[i]); err != nil {
   606  			return err
   607  		}
   608  	}
   609  	return nil
   610  }
   611  
   612  func prepareTLVTableMaps() []*TLVTableMap {
   613  	tlvMap1 := &TLVTableMap{
   614  		OptClass:  0xffff,
   615  		OptType:   0,
   616  		OptLength: 16,
   617  		Index:     0,
   618  	}
   619  	tlvMap2 := &TLVTableMap{
   620  		OptClass:  0xffff,
   621  		OptType:   1,
   622  		OptLength: 16,
   623  		Index:     1,
   624  	}
   625  	return []*TLVTableMap{tlvMap1, tlvMap2}
   626  }
   627  
   628  func prepareTLVTableMod() *TLVTableMod {
   629  
   630  	tlvMapMod := &TLVTableMod{
   631  		Command: NXTTMC_ADD,
   632  		TlvMaps: prepareTLVTableMaps(),
   633  	}
   634  	return tlvMapMod
   635  }
   636  func tlvMapEquals(oriTlvMap, newTlvMap *TLVTableMap) error {
   637  	if oriTlvMap.OptClass != newTlvMap.OptClass {
   638  		return errors.New("TLVTableMap option: Class not equal")
   639  	}
   640  	if oriTlvMap.OptLength != newTlvMap.OptLength {
   641  		return errors.New("TLVTableMap option: Length not equal")
   642  	}
   643  	if oriTlvMap.OptType != newTlvMap.OptType {
   644  		return errors.New("TLVTableMap option: Type not equal")
   645  	}
   646  	if oriTlvMap.Index != newTlvMap.Index {
   647  		return errors.New("TLVTableMap option: Index not equal")
   648  	}
   649  	return nil
   650  }
   651  
   652  func prepareLearnSpecs() []*NXLearnSpec {
   653  	srcValue1 := make([]byte, 2)
   654  	binary.BigEndian.PutUint16(srcValue1, 99)
   655  	dstField1, _ := FindFieldHeaderByName("NXM_OF_IN_PORT", false)
   656  	dstSpecField1 := &NXLearnSpecField{dstField1, 0}
   657  	srcField2, _ := FindFieldHeaderByName("NXM_OF_ETH_SRC", false)
   658  	srcSpecField2 := &NXLearnSpecField{srcField2, 0}
   659  	dstField2, _ := FindFieldHeaderByName("NXM_OF_ETH_DST", false)
   660  	dstSpecField2 := &NXLearnSpecField{dstField2, 0}
   661  	srcField3, _ := FindFieldHeaderByName("NXM_OF_IN_PORT", false)
   662  	srcSpecField3 := &NXLearnSpecField{srcField3, 0}
   663  	dstField3, _ := FindFieldHeaderByName("NXM_NX_REG1", false)
   664  	dstSpecField3 := &NXLearnSpecField{dstField3, 16}
   665  	srcValue4, _ := hex.DecodeString("aabbccddeeff")
   666  	dstField4, _ := FindFieldHeaderByName("NXM_OF_ETH_SRC", false)
   667  	dstSpecField4 := &NXLearnSpecField{dstField4, 0}
   668  	srcField5, _ := FindFieldHeaderByName("NXM_OF_IN_PORT", false)
   669  	srcSpecField5 := &NXLearnSpecField{srcField5, 0}
   670  	return []*NXLearnSpec{
   671  		{Header: NewLearnHeaderMatchFromValue(16), SrcValue: srcValue1, DstField: dstSpecField1},
   672  		{Header: NewLearnHeaderMatchFromField(48), SrcField: srcSpecField2, DstField: dstSpecField2},
   673  		{Header: NewLearnHeaderLoadFromField(16), SrcField: srcSpecField3, DstField: dstSpecField3},
   674  		{Header: NewLearnHeaderLoadFromValue(48), SrcValue: srcValue4, DstField: dstSpecField4},
   675  		{Header: NewLearnHeaderOutputFromField(16), SrcField: srcSpecField5},
   676  	}
   677  }
   678  
   679  func nsLearnEquals(oriAction, newAction *NXActionLearn) error {
   680  	if oriAction.IdleTimeout != newAction.IdleTimeout {
   681  		return errors.New("learn idleTimeout not equal")
   682  	}
   683  	if oriAction.HardTimeout != newAction.HardTimeout {
   684  		return errors.New("learn hardTimeout not equal")
   685  	}
   686  	if oriAction.Priority != newAction.Priority {
   687  		return errors.New("learn priority not equal")
   688  	}
   689  	if oriAction.Flags != newAction.Flags {
   690  		return errors.New("learn cookie not equal")
   691  	}
   692  	if oriAction.Cookie != newAction.Cookie {
   693  		return errors.New("learn cookie not equal")
   694  	}
   695  	if oriAction.TableID != newAction.TableID {
   696  		return errors.New("learn table not equal")
   697  	}
   698  	if oriAction.FinIdleTimeout != newAction.FinIdleTimeout {
   699  		return errors.New("learn finIdleTimeout not equal")
   700  	}
   701  	if oriAction.FinHardTimeout != newAction.FinHardTimeout {
   702  		return errors.New("learn finHardTimeout not equal")
   703  	}
   704  	if len(oriAction.LearnSpecs) != len(newAction.LearnSpecs) {
   705  		return errors.New("learn spec count not equal")
   706  	}
   707  	for idx := range oriAction.LearnSpecs {
   708  		oriSpec := oriAction.LearnSpecs[idx]
   709  		newSpec := newAction.LearnSpecs[idx]
   710  		if err := nxLearnSpecEquals(oriSpec, newSpec); err != nil {
   711  			return err
   712  		}
   713  	}
   714  
   715  	return nil
   716  }
   717  
   718  func nxLearnSpecEquals(oriSpec, newSpec *NXLearnSpec) error {
   719  	if err := nxLearnSpecHeaderEquals(oriSpec.Header, newSpec.Header); err != nil {
   720  		return err
   721  	}
   722  	if err := nxLearnSpecFieldEquals(oriSpec.SrcField, newSpec.SrcField); err != nil {
   723  		return err
   724  	}
   725  	if err := nxLearnSpecFieldEquals(oriSpec.DstField, newSpec.DstField); err != nil {
   726  		return err
   727  	}
   728  	if !bytes.Equal(oriSpec.SrcValue, newSpec.SrcValue) {
   729  		errors.New("spec src value not equal")
   730  	}
   731  	return nil
   732  }
   733  
   734  func nxLearnSpecFieldEquals(oriField, newField *NXLearnSpecField) error {
   735  	if (oriField != nil && newField == nil) || (oriField == nil && newField != nil) {
   736  		return errors.New("spec field not equal")
   737  	}
   738  	if oriField != nil && newField != nil {
   739  		if oriField.Ofs != newField.Ofs {
   740  			return errors.New("spec ofs not equal")
   741  		}
   742  		oriFieldHeader := oriField.Field.MarshalHeader()
   743  		newFieldHeader := newField.Field.MarshalHeader()
   744  		if oriFieldHeader != newFieldHeader {
   745  			return errors.New("spec field header not equal")
   746  		}
   747  	}
   748  	return nil
   749  }
   750  
   751  func nxLearnSpecHeaderEquals(oriHeader, newHeader *NXLearnSpecHeader) error {
   752  	if oriHeader.length != newHeader.length {
   753  		return errors.New("header length not equal")
   754  	}
   755  	if oriHeader.src != newHeader.src {
   756  		return errors.New("header src not equal")
   757  	}
   758  	if oriHeader.dst != newHeader.dst {
   759  		return errors.New("header dst not equal")
   760  	}
   761  	if oriHeader.nBits != newHeader.nBits {
   762  		return errors.New("header nBits not equal")
   763  	}
   764  	if oriHeader.output != newHeader.output {
   765  		return errors.New("header output not equal")
   766  	}
   767  	return nil
   768  }
   769  
   770  func translateMessages(t *testing.T, act1, act2 Action, compare func(act1, act2 Action, stype uint16) bool) {
   771  	data, err := act1.MarshalBinary()
   772  	if err != nil {
   773  		t.Fatalf("Failed to Marshal message: %v", err)
   774  	}
   775  	err = act2.UnmarshalBinary(data)
   776  	if err != nil {
   777  		t.Fatalf("Failed to Unmarshal NXActionCTNAT: %v", err)
   778  	}
   779  	if act1.Header().Type != act1.Header().Type || act1.Header().Type != ActionType_Experimenter {
   780  		t.Errorf("Action type is not equal")
   781  	}
   782  	nxHeader1 := new(NXActionHeader)
   783  	if err = nxHeader1.UnmarshalBinary(data); err != nil {
   784  		t.Fatalf("Failed to unMarshal NXHeader")
   785  	}
   786  	result := compare(act1, act2, nxHeader1.Subtype)
   787  	if !result {
   788  		t.Errorf("Unmarshaled object is not equals to original one")
   789  	}
   790  }
   791  
   792  func nxConjunctionEquals(o1, o2 Action, subtype uint16) bool {
   793  	if subtype != NXAST_CONJUNCTION {
   794  		return false
   795  	}
   796  	obj1 := o1.(*NXActionConjunction)
   797  	obj2 := o2.(*NXActionConjunction)
   798  	if obj1.ID != obj2.ID {
   799  		return false
   800  	}
   801  	if obj1.NClause != obj2.NClause {
   802  		return false
   803  	}
   804  	if obj1.Clause != obj2.Clause {
   805  		return false
   806  	}
   807  	return true
   808  }
   809  
   810  func nxRegLoadEquals(o1, o2 Action, subtype uint16) bool {
   811  	if subtype != NXAST_REG_LOAD {
   812  		return false
   813  	}
   814  	obj1 := o1.(*NXActionRegLoad)
   815  	obj2 := o2.(*NXActionRegLoad)
   816  	if obj1.OfsNbits != obj2.OfsNbits {
   817  		return false
   818  	}
   819  	if obj1.DstReg.Field != obj2.DstReg.Field {
   820  		return false
   821  	}
   822  	if obj1.Value != obj2.Value {
   823  		return false
   824  	}
   825  	return true
   826  }
   827  
   828  func nxRegMoveEquals(o1, o2 Action, subtype uint16) bool {
   829  	if subtype != NXAST_REG_MOVE {
   830  		return false
   831  	}
   832  	obj1 := o1.(*NXActionRegMove)
   833  	obj2 := o2.(*NXActionRegMove)
   834  	if obj1.DstField.Field != obj2.DstField.Field {
   835  		return false
   836  	}
   837  	if obj1.SrcField.Field != obj2.SrcField.Field {
   838  		return false
   839  	}
   840  	if obj1.SrcOfs != obj2.SrcOfs {
   841  		return false
   842  	}
   843  	if obj1.DstOfs != obj2.DstOfs {
   844  		return false
   845  	}
   846  	if obj1.Nbits != obj2.Nbits {
   847  		return false
   848  	}
   849  	return true
   850  }
   851  
   852  func nxOutputRegEquals(o1, o2 Action, subtype uint16) bool {
   853  	if subtype != NXAST_OUTPUT_REG {
   854  		return false
   855  	}
   856  	obj1 := o1.(*NXActionOutputReg)
   857  	obj2 := o2.(*NXActionOutputReg)
   858  	if obj1.SrcField.Field != obj2.SrcField.Field {
   859  		return false
   860  	}
   861  	if obj1.OfsNbits != obj2.OfsNbits {
   862  		return false
   863  	}
   864  	if obj1.MaxLen != obj2.MaxLen {
   865  		return false
   866  	}
   867  	return true
   868  }
   869  
   870  func nxDecTTLEquals(o1 Action, o2 Action, subtype uint16) bool {
   871  	if subtype != NXAST_DEC_TTL {
   872  		return false
   873  	}
   874  	obj1 := o1.(*NXActionDecTTL)
   875  	obj2 := o2.(*NXActionDecTTL)
   876  	if obj1.controllers != obj2.controllers {
   877  		return false
   878  	}
   879  	if obj2.controllers != 0 {
   880  		return false
   881  	}
   882  	return true
   883  }
   884  
   885  func nxDecTTLCntIDsEquals(o1 Action, o2 Action, subtype uint16) bool {
   886  	if subtype != NXAST_DEC_TTL_CNT_IDS {
   887  		return false
   888  	}
   889  	obj1 := o1.(*NXActionDecTTLCntIDs)
   890  	obj2 := o2.(*NXActionDecTTLCntIDs)
   891  	if obj1.controllers != obj2.controllers {
   892  		return false
   893  	}
   894  	if len(obj1.cntIDs) != len(obj2.cntIDs) {
   895  		return false
   896  	}
   897  	obj1CntMap := make(map[uint16]bool)
   898  	for _, id := range obj1.cntIDs {
   899  		obj1CntMap[id] = true
   900  	}
   901  
   902  	for _, id := range obj2.cntIDs {
   903  		_, exist := obj1CntMap[id]
   904  		if !exist {
   905  			return false
   906  		}
   907  	}
   908  	return true
   909  }
   910  
   911  func testMatchFieldHeaderMarshalUnMarshal(tgtField *MatchField, t *testing.T) {
   912  	headerInt := tgtField.MarshalHeader()
   913  	testMFHeader := new(MatchField)
   914  	var data = make([]byte, 4)
   915  	binary.BigEndian.PutUint32(data, headerInt)
   916  	err := testMFHeader.UnmarshalHeader(data)
   917  	if err != nil {
   918  		t.Errorf("Failed to UnmarshalHeader: %v", err)
   919  	}
   920  	if testMFHeader.Class != tgtField.Class {
   921  		t.Errorf("Unmarshalled header has incorrect 'Class' field, expect: %d, actual: %d", testMFHeader.Class, tgtField.Class)
   922  	}
   923  	if testMFHeader.Field != tgtField.Field {
   924  		t.Errorf("Unmarshalled header has incorrect 'Field' field, expect: %d, actual: %d", testMFHeader.Field, tgtField.Field)
   925  	}
   926  	if testMFHeader.HasMask != tgtField.HasMask {
   927  		t.Errorf("Unmarshalled header has incorrect 'HasMask' field, expect: %v, actual: %v", testMFHeader.HasMask, tgtField.HasMask)
   928  	}
   929  	if testMFHeader.Length != tgtField.Length {
   930  		t.Errorf("Unmarshalled header has incorrect 'Length' field, expect: %d, actual: %d", testMFHeader.Length, tgtField.Length)
   931  	}
   932  }