func TestUsmUpdateEngineBootsTime(t *testing.T) {
	sec := snmpclient2.NewUsm().(*snmpclient2.USM)

	sec.UpdatedTime = time.Unix(time.Now().Unix()-int64(10), 0)
	err := sec.UpdateEngineBootsTime()
	if err != nil || sec.AuthEngineTime < 9 || sec.AuthEngineTime > 11 {
		t.Error("EngineBootsTime() - update authEnginetime")
	}

	sec.UpdatedTime = time.Unix(time.Now().Unix()-int64(10), 0)
	sec.AuthEngineTime = math.MaxInt32
	err = sec.UpdateEngineBootsTime()
	if err != nil || sec.AuthEngineBoots != 1 ||
		(sec.AuthEngineTime < 9 || sec.AuthEngineTime > 11) {
		t.Error("EngineBootsTime() - carry-over authEngineBoots")
	}

	sec.UpdatedTime = time.Unix(time.Now().Unix()-int64(10), 0)
	sec.AuthEngineBoots = math.MaxInt32 - 1
	sec.AuthEngineTime = math.MaxInt32
	err = sec.UpdateEngineBootsTime()
	if err == nil {
		t.Error("EngineBootsTime() - max authEngineBoots")
	}
}
func TestUsmTimeliness(t *testing.T) {
	sec := snmpclient2.NewUsm().(*snmpclient2.USM)

	err := sec.CheckTimeliness(math.MaxInt32, 0)
	if err == nil {
		t.Error("Timeliness() - max authEngineBoots")
	}

	sec.AuthEngineBoots = 1
	err = sec.CheckTimeliness(0, 0)
	if err == nil {
		t.Error("Timeliness() - lose authEngineBoots")
	}

	sec.AuthEngineBoots = 0
	err = sec.CheckTimeliness(0, 151)
	if err == nil {
		t.Error("Timeliness() - lose authEngineTime")
	}

	err = sec.CheckTimeliness(0, 150)
	if err != nil {
		t.Errorf("Timeliness() - has error %v", err)
	}
}
func aTestUsm(t *testing.T) {
	expUser := []byte("myUser")
	expEngId := []byte{0x80, 0x00, 0x00, 0x00, 0x01}
	expCtxId := []byte{0x80, 0x00, 0x00, 0x00, 0x05}
	expCtxName := "myName"
	snmp, _ := snmpclient2.NewSNMP("udp", "127.0.0.1",
		snmpclient2.Arguments{
			Version:         snmpclient2.V3,
			UserName:        string(expUser),
			SecurityLevel:   snmpclient2.AuthPriv,
			AuthPassword:    "******",
			AuthProtocol:    snmpclient2.Md5,
			PrivPassword:    "******",
			PrivProtocol:    snmpclient2.Des,
			ContextEngineId: hex.EncodeToString(expCtxId),
			ContextName:     expCtxName,
		})
	sec := snmpclient2.NewUsm().(*snmpclient2.USM)
	pdu := snmpclient2.NewPdu(snmpclient2.V3, snmpclient2.GetRequest)
	spdu := pdu.(*snmpclient2.ScopedPdu)
	smsg := snmpclient2.NewMessage(snmpclient2.V3, pdu).(*snmpclient2.MessageV3)
	smsg.SetAuthentication(false)
	smsg.SetPrivacy(false)

	// Discovery
	err := sec.GenerateRequestMessage(snmpclient2.GetArgs(snmp), smsg)
	if err != nil {
		t.Errorf("GenerateRequestMessage() - has error %v", err)
	}
	if !bytes.Equal(spdu.ContextEngineId, expCtxId) {
		t.Errorf("GenerateRequestMessage() - expected [%s], actual [%s]",
			expCtxId, spdu.ContextEngineId)
	}
	if string(spdu.ContextName) != expCtxName {
		t.Errorf("GenerateRequestMessage() - expected [%s], actual [%s]",
			expCtxName, string(spdu.ContextName))
	}
	if len(smsg.PduBytes()) == 0 {
		t.Error("GenerateRequestMessage() - pdu marshal")
	}

	pdu = snmpclient2.NewPdu(snmpclient2.V3, snmpclient2.Report)
	rmsg := snmpclient2.NewMessage(snmpclient2.V3, pdu).(*snmpclient2.MessageV3)
	rmsg.SetPduBytes(smsg.PduBytes())
	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err == nil {
		t.Error("ProcessIncomingMessage() - engineId check")
	}

	rmsg.AuthEngineId = expEngId
	rmsg.AuthEngineBoots = -1
	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err == nil {
		t.Error("ProcessIncomingMessage() - boots check")
	}

	rmsg.AuthEngineBoots = 1
	rmsg.AuthEngineTime = -1
	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err == nil {
		t.Error("ProcessIncomingMessage() - time check")
	}

	rmsg.AuthEngineTime = 1
	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err != nil {
		t.Errorf("ProcessIncomingMessage() - has error %v", err)
	}
	if !bytes.Equal(sec.AuthEngineId, expEngId) {
		t.Errorf("ProcessIncomingMessage() - expected [%s], actual [%s]",
			sec.AuthEngineId, expEngId)
	}
	// if len(sec.AuthKey) == 0 {
	// 	t.Error("ProcessIncomingMessage() - authKey")
	// }
	// if len(sec.PrivKey) == 0 {
	// 	t.Error("ProcessIncomingMessage() - privKey")
	// }

	// Synchronize
	smsg.SetAuthentication(true)
	smsg.SetPrivacy(true)

	err = sec.GenerateRequestMessage(snmpclient2.GetArgs(snmp), smsg)
	if err != nil {
		t.Errorf("GenerateRequestMessage() - has error %v", err)
	}
	if !bytes.Equal(smsg.UserName, expUser) {
		t.Errorf("GenerateRequestMessage() - expected [%s], actual [%s]",
			expUser, smsg.UserName)
	}
	if !bytes.Equal(smsg.AuthEngineId, expEngId) {
		t.Errorf("GenerateRequestMessage() - expected [%s], actual [%s]",
			expEngId, smsg.AuthEngineId)
	}
	if len(smsg.PrivParameter) == 0 {
		t.Error("GenerateRequestMessage() - privParameter")
	}
	if len(smsg.AuthParameter) == 0 {
		t.Error("GenerateRequestMessage() - authParameter")
	}

	pdu = snmpclient2.NewPdu(snmpclient2.V3, snmpclient2.Report)
	rmsg = snmpclient2.NewMessage(snmpclient2.V3, pdu).(*snmpclient2.MessageV3)
	rmsg.SetAuthentication(true)
	rmsg.SetPrivacy(true)
	rmsg.SetPduBytes(smsg.PduBytes())
	rmsg.AuthEngineId = []byte("foobar")
	rmsg.AuthEngineBoots = smsg.AuthEngineBoots
	rmsg.AuthEngineTime = smsg.AuthEngineTime
	rmsg.PrivParameter = smsg.PrivParameter
	rmsg.AuthParameter = smsg.AuthParameter

	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err == nil {
		t.Error("ProcessIncomingMessage() - userName check")
	}

	rmsg.UserName = expUser
	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err == nil {
		t.Error("ProcessIncomingMessage() - authEngine check")
	}

	rmsg.AuthEngineId = expEngId
	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err != nil {
		t.Errorf("ProcessIncomingMessage() - has error %v", err)
	}
	if sec.AuthEngineBoots != rmsg.AuthEngineBoots {
		t.Error("ProcessIncomingMessage() - engineBoots")
	}
	if sec.AuthEngineTime != rmsg.AuthEngineTime {
		t.Error("ProcessIncomingMessage() - engineTime")
	}

	// Request
	sec.AuthEngineBoots = 1
	sec.AuthEngineTime = 1

	err = sec.GenerateRequestMessage(snmpclient2.GetArgs(snmp), smsg)
	if err != nil {
		t.Errorf("GenerateRequestMessage() - has error %v", err)
	}
	if smsg.AuthEngineBoots != sec.AuthEngineBoots {
		t.Errorf("GenerateRequestMessage() - expected [%d], actual [%d]",
			sec.AuthEngineBoots, smsg.AuthEngineBoots)
	}
	if smsg.AuthEngineTime != sec.AuthEngineTime {
		t.Errorf("GenerateRequestMessage() - expected [%d], actual [%d]",
			sec.AuthEngineTime, smsg.AuthEngineTime)
	}

	pdu = snmpclient2.NewPdu(snmpclient2.V3, snmpclient2.GetResponse)
	spdu = pdu.(*snmpclient2.ScopedPdu)
	rmsg = snmpclient2.NewMessage(snmpclient2.V3, pdu).(*snmpclient2.MessageV3)
	rmsg.AuthEngineId = expEngId
	rmsg.AuthEngineBoots = smsg.AuthEngineBoots
	rmsg.AuthEngineTime = smsg.AuthEngineTime
	rmsg.UserName = expUser

	// set PduBytes with GetResponse
	b, _ := spdu.Marshal()
	rmsg.SetPduBytes(b)

	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err == nil {
		t.Error("ProcessIncomingMessage() - contextEngineId check")
	}

	// set PduBytes with ContextEngineId
	spdu.ContextEngineId = expCtxId
	b, _ = spdu.Marshal()
	rmsg.SetPduBytes(b)
	err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	if err == nil {
		t.Error("ProcessIncomingMessage() - contextName check")
	}

	// // set PduBytes with ContextName
	// spdu.ContextName = []byte(expCtxName)
	// b, _ = spdu.Marshal()
	// rmsg.SetPduBytes(b)
	// err = sec.ProcessIncomingMessage(snmpclient2.GetArgs(snmp), rmsg)
	// if err == nil {
	// 	t.Error("ProcessIncomingMessage() - response authenticate check")
	// }
}