github.com/ks888/tgo@v0.0.0-20190130135156-80bf89407292/debugapi/client_darwin_test.go (about) 1 package debugapi 2 3 import ( 4 "bytes" 5 "fmt" 6 "net" 7 "os" 8 "os/exec" 9 "path" 10 "strconv" 11 "strings" 12 "syscall" 13 "testing" 14 "time" 15 16 "github.com/ks888/tgo/testutils" 17 "golang.org/x/sys/unix" 18 ) 19 20 func TestCheckInterface(t *testing.T) { 21 var _ client = NewClient() 22 } 23 24 func TestLaunchProcess(t *testing.T) { 25 client := NewClient() 26 err := client.LaunchProcess(testutils.ProgramInfloop) 27 if err != nil { 28 t.Fatalf("failed to launch process: %v", err) 29 } 30 defer client.DetachProcess() 31 } 32 33 func TestLaunchProcess_ProgramNotExist(t *testing.T) { 34 client := NewClient() 35 err := client.LaunchProcess("notexist") 36 if err == nil { 37 t.Fatalf("error not returned") 38 } 39 } 40 41 func TestAttachProcess(t *testing.T) { 42 cmd := exec.Command(testutils.ProgramInfloop) 43 _ = cmd.Start() 44 45 client := NewClient() 46 err := client.AttachProcess(cmd.Process.Pid) 47 if err != nil { 48 t.Fatalf("failed to launch process: %v", err) 49 } 50 client.DetachProcess() // must detach before kill. Otherwise, the program becomes zombie. 51 cmd.Process.Kill() 52 cmd.Process.Wait() 53 } 54 55 func TestAttachProcess_WrongPID(t *testing.T) { 56 client := NewClient() 57 cmd := exec.Command(testutils.ProgramHelloworld) 58 _ = cmd.Run() 59 60 // the program already exits, so the pid is wrong 61 err := client.AttachProcess(cmd.Process.Pid) 62 if err == nil { 63 t.Fatalf("error should be returned") 64 } 65 } 66 67 func TestDetachProcess_KillProc(t *testing.T) { 68 client := NewClient() 69 err := client.LaunchProcess(testutils.ProgramInfloop) 70 if err != nil { 71 t.Fatalf("failed to launch process: %v", err) 72 } 73 defer client.DetachProcess() 74 75 debugeeProcID, _ := findProcessID(path.Base(testutils.ProgramInfloop), client.pid) 76 77 if err := client.DetachProcess(); err != nil { 78 t.Fatalf("failed to detach from the process: %v", err) 79 } 80 81 // it often takes some times to finish the debug server and debugee. 82 for i := 0; i < 10; i++ { 83 if !existsPid(debugeeProcID) { 84 break 85 } 86 time.Sleep(100 * time.Millisecond) 87 } 88 if existsPid(debugeeProcID) { 89 t.Errorf("the debugee process is still alive") 90 } 91 } 92 93 func TestReadRegisters(t *testing.T) { 94 client := NewClient() 95 err := client.LaunchProcess(testutils.ProgramInfloop) 96 if err != nil { 97 t.Fatalf("failed to launch process: %v", err) 98 } 99 defer client.DetachProcess() 100 101 if err := client.WriteMemory(testutils.InfloopAddrMain, []byte{0xcc}); err != nil { 102 t.Fatalf("failed to write memory: %v", err) 103 } 104 event, err := client.ContinueAndWait() 105 if err != nil { 106 t.Fatalf("failed to continue and wait: %v", err) 107 } 108 threadIDs := event.Data.([]int) 109 110 regs, err := client.ReadRegisters(threadIDs[0]) 111 if err != nil { 112 t.Fatalf("failed to read registers: %v", err) 113 } 114 if regs.Rip != uint64(testutils.InfloopAddrMain+1) { 115 t.Fatalf("wrong rip: %x", regs.Rip) 116 } 117 if regs.Rsp == 0 { 118 t.Fatalf("empty rsp: %x", regs.Rsp) 119 } 120 } 121 122 func TestWriteRegisters(t *testing.T) { 123 client := NewClient() 124 err := client.LaunchProcess(testutils.ProgramInfloop) 125 if err != nil { 126 t.Fatalf("failed to launch process: %v", err) 127 } 128 defer client.DetachProcess() 129 130 threadIDs, err := client.ThreadIDs() 131 if err != nil { 132 t.Fatalf("failed to get thread ids: %v", err) 133 } 134 135 regs := Registers{Rip: 0x1, Rsp: 0x2, Rcx: 0x3} 136 if err := client.WriteRegisters(threadIDs[0], regs); err != nil { 137 t.Fatalf("failed to write registers: %v", err) 138 } 139 140 actualRegs, _ := client.ReadRegisters(threadIDs[0]) 141 if actualRegs.Rip != 0x1 { 142 t.Errorf("wrong rip: %x", actualRegs.Rip) 143 } 144 if actualRegs.Rsp != 0x2 { 145 t.Errorf("wrong rsp: %x", actualRegs.Rsp) 146 } 147 if actualRegs.Rcx != 0x3 { 148 t.Errorf("wrong rcx: %x", actualRegs.Rcx) 149 } 150 } 151 152 func TestAllocateMemory(t *testing.T) { 153 client := NewClient() 154 err := client.LaunchProcess(testutils.ProgramInfloop) 155 if err != nil { 156 t.Fatalf("failed to launch process: %v", err) 157 } 158 defer client.DetachProcess() 159 160 addr, err := client.allocateMemory(1) 161 if err != nil { 162 t.Fatalf("failed to allocate memory: %v", err) 163 } 164 165 if addr == 0 { 166 t.Errorf("empty addr: %x", addr) 167 } 168 } 169 170 func TestDeallocateMemory(t *testing.T) { 171 client := NewClient() 172 err := client.LaunchProcess(testutils.ProgramInfloop) 173 if err != nil { 174 t.Fatalf("failed to launch process: %v", err) 175 } 176 defer client.DetachProcess() 177 178 addr, _ := client.allocateMemory(1) 179 err = client.deallocateMemory(addr) 180 if err != nil { 181 t.Fatalf("failed to deallocate memory: %v", err) 182 } 183 } 184 185 func TestReadMemory(t *testing.T) { 186 client := NewClient() 187 err := client.LaunchProcess(testutils.ProgramInfloop) 188 if err != nil { 189 t.Fatalf("failed to launch process: %v", err) 190 } 191 defer client.DetachProcess() 192 193 out := make([]byte, 2) 194 err = client.ReadMemory(testutils.InfloopAddrMain, out) 195 if err != nil { 196 t.Fatalf("failed to read memory: %v", err) 197 } 198 199 if out[0] != 0x65 || out[1] != 0x48 { 200 t.Errorf("wrong memory: %v", out) 201 } 202 } 203 204 func TestReadMemory_LargeSize(t *testing.T) { 205 client := NewClient() 206 err := client.LaunchProcess(testutils.ProgramInfloop) 207 if err != nil { 208 t.Fatalf("failed to launch process: %v", err) 209 } 210 defer client.DetachProcess() 211 212 out := make([]byte, 2048) 213 err = client.ReadMemory(testutils.InfloopAddrMain, out) 214 if err != nil { 215 t.Fatalf("failed to read memory: %v", err) 216 } 217 218 if out[0] != 0x65 || out[1] != 0x48 { 219 t.Errorf("wrong memory: %v", out) 220 } 221 } 222 223 func TestWriteMemory(t *testing.T) { 224 client := NewClient() 225 err := client.LaunchProcess(testutils.ProgramInfloop) 226 if err != nil { 227 t.Fatalf("failed to launch process: %v", err) 228 } 229 defer client.DetachProcess() 230 231 data := []byte{0x1, 0x2, 0x3, 0x4} 232 err = client.WriteMemory(testutils.InfloopAddrMain, data) 233 if err != nil { 234 t.Fatalf("failed to write memory: %v", err) 235 } 236 237 actual := make([]byte, 4) 238 _ = client.ReadMemory(testutils.InfloopAddrMain, actual) 239 if actual[0] != 0x1 || actual[1] != 0x2 || actual[2] != 0x3 || actual[3] != 0x4 { 240 t.Errorf("wrong memory: %v", actual) 241 } 242 243 } 244 245 func TestReadTLS(t *testing.T) { 246 client := NewClient() 247 err := client.LaunchProcess(testutils.ProgramInfloop) 248 if err != nil { 249 t.Fatalf("failed to launch process: %v", err) 250 } 251 defer client.DetachProcess() 252 253 _ = client.WriteMemory(testutils.InfloopAddrMain, []byte{0xcc}) 254 event, _ := client.ContinueAndWait() 255 threadIDs := event.Data.([]int) 256 257 _, err = client.ReadTLS(threadIDs[0], 0xf) 258 if err != nil { 259 t.Fatalf("failed to read tls: %v", err) 260 } 261 } 262 263 func TestContinueAndWait_Trapped(t *testing.T) { 264 client := NewClient() 265 err := client.LaunchProcess(testutils.ProgramInfloop) 266 if err != nil { 267 t.Fatalf("failed to launch process: %v", err) 268 } 269 defer client.DetachProcess() 270 271 out := []byte{0xcc} 272 err = client.WriteMemory(testutils.InfloopAddrMain, out) 273 if err != nil { 274 t.Fatalf("failed to write memory: %v", err) 275 } 276 277 event, err := client.ContinueAndWait() 278 threadIDs := event.Data.([]int) 279 if err != nil { 280 t.Fatalf("failed to continue and wait: %v", err) 281 } 282 if len(threadIDs) == 0 { 283 t.Errorf("empty threadIDs") 284 } 285 if event.Type != EventTypeTrapped { 286 t.Errorf("wrong event type: %v", event.Type) 287 } 288 } 289 290 func TestContinueAndWait_Exited(t *testing.T) { 291 client := NewClient() 292 err := client.LaunchProcess(testutils.ProgramHelloworld) 293 if err != nil { 294 t.Fatalf("failed to launch process: %v", err) 295 } 296 defer client.DetachProcess() 297 298 for { 299 event, err := client.ContinueAndWait() 300 if err != nil { 301 t.Fatalf("failed to continue and wait: %v", err) 302 } 303 if event == (Event{Type: EventTypeExited, Data: 0}) { 304 break 305 } 306 } 307 } 308 309 func TestContinueAndWait_ConsoleWrite(t *testing.T) { 310 client := NewClient() 311 buff := &bytes.Buffer{} 312 client.outputWriter = buff 313 err := client.LaunchProcess(testutils.ProgramHelloworld) 314 if err != nil { 315 t.Fatalf("failed to launch process: %v", err) 316 } 317 defer client.DetachProcess() 318 319 for { 320 _, err := client.ContinueAndWait() 321 if err != nil { 322 t.Fatalf("failed to continue and wait: %v", err) 323 } 324 if strings.Contains(buff.String(), "Hello world") { 325 break 326 } 327 } 328 } 329 330 func TestContinueAndWait_Signaled(t *testing.T) { 331 client := NewClient() 332 err := client.LaunchProcess(testutils.ProgramInfloop) 333 if err != nil { 334 t.Fatalf("failed to launch process: %v", err) 335 } 336 defer client.DetachProcess() 337 338 pid, _ := findProcessID(path.Base(testutils.ProgramInfloop), client.pid) 339 _ = sendSignal(pid, unix.SIGKILL) // SIGTERM is not passed to the debugee 340 341 event, err := client.ContinueAndWait() 342 if err != nil { 343 t.Fatalf("failed to continue and wait: %v", err) 344 } 345 if event != (Event{Type: EventTypeTerminated, Data: 0}) { 346 t.Fatalf("wrong event: %v", event) 347 } 348 } 349 350 // No test for CoreDump as the debugserver does not pass the signals like SIGQUIT to the debugee. 351 352 func TestStepAndWait(t *testing.T) { 353 client := NewClient() 354 err := client.LaunchProcess(testutils.ProgramInfloop) 355 if err != nil { 356 t.Fatalf("failed to launch process: %v", err) 357 } 358 defer client.DetachProcess() 359 360 threadIDs, err := client.ThreadIDs() 361 if err != nil { 362 t.Fatalf("failed to get thread ids: %v", err) 363 } 364 365 event, err := client.StepAndWait(threadIDs[0]) 366 if err != nil { 367 t.Fatalf("failed to step and wait: %v", err) 368 } 369 if event.Type != EventTypeTrapped { 370 t.Fatalf("wrong event type: %v", event.Type) 371 } 372 } 373 374 func TestStepAndWait_StopAtBreakpoint(t *testing.T) { 375 client := NewClient() 376 err := client.LaunchProcess(testutils.ProgramInfloop) 377 if err != nil { 378 t.Fatalf("failed to launch process: %v", err) 379 } 380 defer client.DetachProcess() 381 382 orgInsts := make([]byte, 1) 383 _ = client.ReadMemory(testutils.InfloopAddrMain, orgInsts) 384 _ = client.WriteMemory(testutils.InfloopAddrMain, []byte{0xcc}) 385 event, _ := client.ContinueAndWait() 386 threadIDs := event.Data.([]int) 387 388 regs, _ := client.ReadRegisters(threadIDs[0]) 389 regs.Rip-- 390 _ = client.WriteRegisters(threadIDs[0], regs) 391 _ = client.WriteMemory(testutils.InfloopAddrMain, orgInsts) 392 393 _, err = client.StepAndWait(threadIDs[0]) 394 if err != nil { 395 t.Fatalf("failed to step and wait: %v", err) 396 } 397 398 regs, _ = client.ReadRegisters(threadIDs[0]) 399 if regs.Rip != uint64(testutils.InfloopAddrMain)+9 { 400 t.Errorf("wrong pc: %x", regs.Rip) 401 } 402 } 403 404 func TestStepAndWait_UnspecifiedThread(t *testing.T) { 405 client := NewClient() 406 err := client.LaunchProcess(testutils.ProgramInfloop) 407 if err != nil { 408 t.Fatalf("failed to launch process: %v", err) 409 } 410 defer client.DetachProcess() 411 412 orgInsts := make([]byte, 1) 413 _ = client.ReadMemory(testutils.InfloopAddrMain, orgInsts) 414 _ = client.WriteMemory(testutils.InfloopAddrMain, []byte{0xcc}) 415 event, _ := client.ContinueAndWait() 416 threadIDs := event.Data.([]int) 417 418 regs, _ := client.ReadRegisters(threadIDs[0]) 419 regs.Rip-- 420 _ = client.WriteRegisters(threadIDs[0], regs) 421 _ = client.WriteMemory(testutils.InfloopAddrMain, orgInsts) 422 423 _, err = client.StepAndWait(0) 424 if _, ok := err.(UnspecifiedThreadError); !ok { 425 t.Fatalf("not UnspecifiedThreadError: %v", err) 426 } 427 fmt.Println(err) 428 } 429 430 func findProcessID(progName string, parentPID int) (int, error) { 431 out, err := exec.Command("pgrep", "-P", strconv.Itoa(parentPID), progName).Output() 432 if err != nil { 433 return 0, err 434 } 435 436 return strconv.Atoi(string(out[0 : len(out)-1])) // remove newline 437 } 438 439 func existsPid(pid int) bool { 440 process, err := os.FindProcess(pid) 441 if err != nil { 442 return false 443 } 444 445 // Signal 0 can be used to check the validity of pid. 446 return process.Signal(syscall.Signal(0)) == nil 447 } 448 449 func sendSignal(pid int, signal syscall.Signal) error { 450 proc, err := os.FindProcess(pid) 451 if err != nil { 452 return err 453 } 454 455 return proc.Signal(signal) 456 } 457 458 func TestSetNoAckMode(t *testing.T) { 459 connForReceive, connForSend := net.Pipe() 460 461 sendDone := make(chan bool) 462 go func(conn net.Conn, ch chan bool) { 463 defer close(ch) 464 465 client := newTestClient(conn, false) 466 if data, err := client.receive(); err != nil { 467 t.Fatalf("failed to receive command: %v", err) 468 } else if data != "QStartNoAckMode" { 469 t.Errorf("unexpected data: %s", data) 470 } 471 472 if err := client.send("OK"); err != nil { 473 t.Fatalf("failed to receive command: %v", err) 474 } 475 }(connForSend, sendDone) 476 477 client := newTestClient(connForReceive, false) 478 479 if err := client.setNoAckMode(); err != nil { 480 t.Errorf("unexpected error: %v", err) 481 } 482 if !client.noAckMode { 483 t.Errorf("ack mode is not set") 484 } 485 486 <-sendDone 487 } 488 489 func TestSetNoAckMode_ErrorReturned(t *testing.T) { 490 connForReceive, connForSend := net.Pipe() 491 492 sendDone := make(chan bool) 493 go func(conn net.Conn, ch chan bool) { 494 defer close(ch) 495 496 client := newTestClient(conn, false) 497 _, _ = client.receive() 498 _ = client.send("E00") 499 }(connForSend, sendDone) 500 501 client := newTestClient(connForReceive, false) 502 503 if err := client.setNoAckMode(); err == nil { 504 t.Errorf("error is not returned") 505 } 506 507 <-sendDone 508 } 509 510 func TestQSupported(t *testing.T) { 511 connForReceive, connForSend := net.Pipe() 512 513 sendDone := make(chan bool) 514 go func(conn net.Conn, ch chan bool) { 515 defer close(ch) 516 517 client := newTestClient(conn, true) 518 if data, err := client.receive(); err != nil { 519 t.Fatalf("failed to receive command: %v", err) 520 } else if data != "qSupported:swbreak+;hwbreak+;no-resumed+" { 521 t.Errorf("unexpected data: %s", data) 522 } 523 524 if err := client.send("qXfer:features:read+;PacketSize=20000;qEcho+"); err != nil { 525 t.Fatalf("failed to send command: %v", err) 526 } 527 }(connForSend, sendDone) 528 529 client := newTestClient(connForReceive, true) 530 531 if err := client.qSupported(); err != nil { 532 t.Errorf("unexpected error: %v", err) 533 } 534 535 <-sendDone 536 } 537 538 func TestCollectRegisterMetadata(t *testing.T) { 539 connForReceive, connForSend := net.Pipe() 540 541 sendDone := make(chan bool) 542 go func(conn net.Conn, ch chan bool) { 543 defer close(ch) 544 545 client := newTestClient(conn, true) 546 _, _ = client.receive() 547 _ = client.send("name:rax;bitsize:64;offset:0;") 548 _, _ = client.receive() 549 _ = client.send("name:rbx;bitsize:64;offset:8;") 550 _, _ = client.receive() 551 _ = client.send("E45") 552 553 }(connForSend, sendDone) 554 555 client := newTestClient(connForReceive, true) 556 557 meatadata, err := client.collectRegisterMetadata() 558 if err != nil { 559 t.Fatalf("unexpected error: %v", err) 560 } 561 if len(meatadata) != 2 { 562 t.Errorf("wrong length of register metadata: %d", len(meatadata)) 563 } 564 565 <-sendDone 566 } 567 568 func TestQRegisterInfo(t *testing.T) { 569 connForReceive, connForSend := net.Pipe() 570 571 sendDone := make(chan bool) 572 go func(conn net.Conn, ch chan bool) { 573 defer close(ch) 574 575 client := newTestClient(conn, true) 576 if data, err := client.receive(); err != nil { 577 t.Fatalf("failed to receive command: %v", err) 578 } else if data != "qRegisterInfo0" { 579 t.Errorf("unexpected data: %s", data) 580 } 581 582 if err := client.send("name:rax;bitsize:64;offset:0;encoding:uint;format:hex;set:General Purpose Registers;ehframe:0;dwarf:0;invalidate-regs:0,15,25,35,39;"); err != nil { 583 t.Fatalf("failed to send response: %v", err) 584 } 585 }(connForSend, sendDone) 586 587 client := newTestClient(connForReceive, true) 588 589 reg, err := client.qRegisterInfo(0) 590 if err != nil { 591 t.Fatalf("unexpected error: %v", err) 592 } 593 if reg.name != "rax" { 594 t.Errorf("wrong name: %s", reg.name) 595 } 596 if reg.offset != 0 { 597 t.Errorf("wrong offset: %d", reg.offset) 598 } 599 if reg.size != 8 { 600 t.Errorf("wrong size: %d", reg.size) 601 } 602 603 <-sendDone 604 } 605 606 func TestQRegisterInfo_EndOfRegisterList(t *testing.T) { 607 connForReceive, connForSend := net.Pipe() 608 609 sendDone := make(chan bool) 610 go func(conn net.Conn, ch chan bool) { 611 defer close(ch) 612 613 client := newTestClient(conn, true) 614 _, _ = client.receive() 615 _ = client.send("E45") 616 }(connForSend, sendDone) 617 618 client := newTestClient(connForReceive, true) 619 620 _, err := client.qRegisterInfo(0) 621 if err != errEndOfList { 622 t.Fatalf("unexpected error: %v", err) 623 } 624 625 <-sendDone 626 } 627 628 func TestQListThreadsInStopReply(t *testing.T) { 629 connForReceive, connForSend := net.Pipe() 630 631 sendDone := make(chan bool) 632 go func(conn net.Conn, ch chan bool) { 633 defer close(ch) 634 635 client := newTestClient(conn, true) 636 if data, err := client.receive(); err != nil { 637 t.Fatalf("failed to receive command: %v", err) 638 } else if data != "QListThreadsInStopReply" { 639 t.Errorf("unexpected data: %s", data) 640 } 641 642 if err := client.send("OK"); err != nil { 643 t.Fatalf("failed to send command: %v", err) 644 } 645 }(connForSend, sendDone) 646 647 client := newTestClient(connForReceive, true) 648 649 if err := client.qListThreadsInStopReply(); err != nil { 650 t.Errorf("unexpected error: %v", err) 651 } 652 653 <-sendDone 654 } 655 656 func TestQfThreadInfo(t *testing.T) { 657 connForReceive, connForSend := net.Pipe() 658 659 sendDone := make(chan bool) 660 go func(conn net.Conn, ch chan bool) { 661 defer close(ch) 662 663 client := newTestClient(conn, true) 664 if data, err := client.receive(); err != nil { 665 t.Fatalf("failed to receive command: %v", err) 666 } else if data != "qfThreadInfo" { 667 t.Errorf("unexpected data: %s", data) 668 } 669 670 if err := client.send("m15296fb"); err != nil { 671 t.Fatalf("failed to send command: %v", err) 672 } 673 }(connForSend, sendDone) 674 675 client := newTestClient(connForReceive, true) 676 677 threadID, err := client.qfThreadInfo() 678 if err != nil { 679 t.Errorf("unexpected error: %v", err) 680 } 681 if threadID != "15296fb" { 682 t.Errorf("unexpected threadID: %v", threadID) 683 } 684 685 <-sendDone 686 } 687 688 func TestSendAndReceive(t *testing.T) { 689 connForReceive, connForSend := net.Pipe() 690 cmd := "command" 691 692 sendDone := make(chan bool) 693 go func(conn net.Conn, ch chan bool) { 694 defer close(ch) 695 696 client := newTestClient(conn, false) 697 if err := client.send(cmd); err != nil { 698 t.Fatalf("failed to send command: %v", err) 699 } 700 }(connForSend, sendDone) 701 702 client := newTestClient(connForReceive, false) 703 buff, err := client.receive() 704 if err != nil { 705 t.Fatalf("unexpected error: %v", err) 706 } 707 if cmd != buff { 708 t.Errorf("receieved unexpected data: %v", buff) 709 } 710 711 <-sendDone 712 } 713 714 func TestSendAndReceive_NoAckMode(t *testing.T) { 715 connForReceive, connForSend := net.Pipe() 716 cmd := "command" 717 718 sendDone := make(chan bool) 719 go func(conn net.Conn, ch chan bool) { 720 defer close(ch) 721 722 client := newTestClient(conn, true) 723 if err := client.send(cmd); err != nil { 724 t.Fatalf("failed to send command: %v", err) 725 } 726 }(connForSend, sendDone) 727 728 client := newTestClient(connForReceive, true) 729 buff, err := client.receive() 730 if err != nil { 731 t.Fatalf("unexpected error: %v", err) 732 } 733 if cmd != buff { 734 t.Errorf("receieved unexpected data: %v", buff) 735 } 736 737 <-sendDone 738 } 739 740 func TestVerifyPacket(t *testing.T) { 741 for i, test := range []struct { 742 packet string 743 expectError bool 744 }{ 745 {packet: "$command#df", expectError: false}, 746 {packet: "#command#df", expectError: true}, 747 {packet: "$command$df", expectError: true}, 748 {packet: "$command#00", expectError: true}, 749 } { 750 actual := verifyPacket(test.packet) 751 if test.expectError && actual == nil { 752 t.Errorf("[%d] error not returned", i) 753 } else if !test.expectError && actual != nil { 754 t.Errorf("[%d] error returned: %v", i, actual) 755 } 756 } 757 } 758 759 func TestHexToUint64(t *testing.T) { 760 for i, test := range []struct { 761 hex string 762 littleEndian bool 763 expected uint64 764 }{ 765 {hex: "00000001", littleEndian: false, expected: 1}, 766 {hex: "00000102", littleEndian: false, expected: 258}, 767 {hex: "02010000", littleEndian: true, expected: 258}, 768 } { 769 actual, _ := hexToUint64(test.hex, test.littleEndian) 770 if test.expected != actual { 771 t.Errorf("[%d] not expected value: %d", i, actual) 772 } 773 } 774 } 775 776 func TestUint64ToHex(t *testing.T) { 777 for i, test := range []struct { 778 input uint64 779 littleEndian bool 780 expected string 781 }{ 782 {input: 1, littleEndian: false, expected: "0000000000000001"}, 783 {input: 258, littleEndian: false, expected: "0000000000000102"}, 784 {input: 258, littleEndian: true, expected: "0201000000000000"}, 785 } { 786 actual := uint64ToHex(test.input, test.littleEndian) 787 if test.expected != actual { 788 t.Errorf("[%d] not expected value: %s", i, actual) 789 } 790 } 791 } 792 793 func TestChecksum(t *testing.T) { 794 for i, data := range []struct { 795 input []byte 796 expected uint8 797 }{ 798 {input: []byte{0x1, 0x2}, expected: 3}, 799 {input: []byte{0x7f, 0x80}, expected: 255}, 800 {input: []byte{0x80, 0x80}, expected: 0}, 801 {input: []byte{0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64}, expected: 0xdf}, 802 } { 803 sum := calcChecksum(data.input) 804 if sum != data.expected { 805 t.Errorf("[%d] wrong checksum: %x", i, sum) 806 } 807 } 808 } 809 810 func newTestClient(conn net.Conn, noAckMode bool) *Client { 811 return &Client{conn: conn, noAckMode: noAckMode, buffer: make([]byte, maxPacketSize)} 812 }