door_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. package door
  2. // Need net, flag for setupSockets
  3. import (
  4. "flag"
  5. "fmt"
  6. "log"
  7. "net"
  8. "os"
  9. "strings"
  10. "testing"
  11. "time"
  12. )
  13. // Should tests not delete the logfiles?
  14. // To make use of this, set KEEP_LOGS bool = true and:
  15. // go test -c; ./door.test -test.v -test.timeout 40s
  16. // Running just one test:
  17. // go test -c; ./door.test -test.run DoorCP437 -test.v
  18. const KEEP_LOGS bool = false
  19. const VERBOSE_TEST bool = false
  20. func TestGoto(t *testing.T) {
  21. GotoMap := map[string][]int{"\x1b[10;20H": {20, 10},
  22. "\x1b[20;10H": {10, 20},
  23. "\x1b[80;120H": {120, 80},
  24. "\x1b[1;1H": {1, 1},
  25. }
  26. for text, code := range GotoMap {
  27. gt := Goto(code[0], code[1])
  28. if text != gt {
  29. t.Errorf("Goto: Expected %#v (%#v), got %#v", text, code, gt)
  30. }
  31. }
  32. }
  33. func TestReadDropfileFail(t *testing.T) {
  34. d := Door{}
  35. defer func() {
  36. if r := recover(); r == nil {
  37. t.Error("ReadDropfile did not panic on missing dropfile.")
  38. }
  39. }()
  40. d.ReadDropfile("This_File_Will_Not_Be_Found")
  41. }
  42. func TestLogfileFailure(t *testing.T) {
  43. tmpFile, err := os.CreateTemp("", "test-*")
  44. if err != nil {
  45. panic("Cannot create temporary file")
  46. }
  47. defer func() {
  48. if r := recover(); r == nil {
  49. t.Error("Init did not panic on logfile error.")
  50. }
  51. }()
  52. // Remember to clean up the file afterwards
  53. defer os.Remove(tmpFile.Name())
  54. // This test should fail before we even need sockets
  55. var fd int = 0
  56. // Create door32.sys file
  57. dfc := DropfileConfig{2, fd, 1800, "Test BBSID", 1701, "Real Username", "Handle", 880, 28, 0, 13}
  58. _, err = tmpFile.WriteString(fmt.Sprintf("%d\n%d\n%d\n%s\n%d\n%s\n%s\n%d\n%d\n%d\n%d\n",
  59. dfc.Comm_type, dfc.Comm_handle, dfc.Baudrate, dfc.BBSID, dfc.User_number, dfc.Real_name, dfc.Handle,
  60. dfc.Security_level, dfc.Time_left, dfc.Emulation, dfc.Node))
  61. if err != nil {
  62. t.Error("tmpFile.WriteString:", err)
  63. }
  64. err = tmpFile.Close()
  65. if err != nil {
  66. t.Error("tmpFile.Close:", err)
  67. }
  68. d := Door{}
  69. // If I call d.Init() more then once flag complains about flag redefined.
  70. // Reset flags
  71. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
  72. // preset commandline args so door can init
  73. os.Args = []string{"door", "-d", tmpFile.Name()}
  74. d.Init("/badname-test")
  75. }
  76. func TestReadDropFile(t *testing.T) {
  77. tmpFile, err := os.CreateTemp("", "test-*")
  78. if err != nil {
  79. panic("Cannot create temporary file")
  80. }
  81. // Clean up the dropfile afterwards
  82. defer os.Remove(tmpFile.Name())
  83. dfc := DropfileConfig{2, 20, 1800, "Test BBSID", 1701, "Real Username", "Handle", 880, 28, 0, 12}
  84. _, err = tmpFile.WriteString(fmt.Sprintf("%d\n%d\n%d\n%s\n%d\n%s\n%s\n%d\n%d\n%d\n%d\n",
  85. dfc.Comm_type, dfc.Comm_handle, dfc.Baudrate, dfc.BBSID, dfc.User_number, dfc.Real_name, dfc.Handle,
  86. dfc.Security_level, dfc.Time_left, dfc.Emulation, dfc.Node))
  87. if err != nil {
  88. t.Error("tmpFile.WriteString:", err)
  89. }
  90. err = tmpFile.Close()
  91. if err != nil {
  92. t.Error("tmpFile.Close:", err)
  93. }
  94. d := Door{}
  95. d.ReadDropfile(tmpFile.Name())
  96. if dfc.Comm_type != d.Config.Comm_type {
  97. t.Errorf("Comm Type expected %#v, got %#v", dfc.Comm_type, d.Config.Comm_type)
  98. }
  99. if dfc.Comm_handle != d.Config.Comm_handle {
  100. t.Errorf("Comm Handle expected %#v, got %#v", dfc.Comm_handle, d.Config.Comm_handle)
  101. }
  102. if dfc.BBSID != d.Config.BBSID {
  103. t.Errorf("BBSID expected %#v, got %#v", dfc.BBSID, d.Config.BBSID)
  104. }
  105. if dfc.User_number != d.Config.User_number {
  106. t.Errorf("User Number expected %#v, got %#v", dfc.User_number, d.Config.User_number)
  107. }
  108. if dfc.Real_name != d.Config.Real_name {
  109. t.Errorf("Real Name expected %#v, got %#v", dfc.Real_name, d.Config.Real_name)
  110. }
  111. if dfc.Handle != d.Config.Handle {
  112. t.Errorf("Handle expected %#v, got %#v", dfc.Handle, d.Config.Handle)
  113. }
  114. if dfc.Time_left != d.Config.Time_left {
  115. t.Errorf("Time Left expected %#v, got %#v", dfc.Time_left, d.Config.Time_left)
  116. }
  117. if dfc.Node != d.Config.Node {
  118. t.Errorf("Node expected %#v, got %#v", dfc.Node, d.Config.Node)
  119. }
  120. start := time.Now()
  121. timeout := time.Now().Add(time.Duration(dfc.Time_left) * time.Minute)
  122. // Verify the start time and timeout values have been set correctly.
  123. startDelta := start.Sub(d.StartTime)
  124. timeoutDelta := timeout.Sub(d.TimeOut)
  125. left := d.TimeLeft()
  126. used := d.TimeUsed()
  127. if used.Seconds() > 1 {
  128. t.Errorf("Time Used (from door) > 1 second: %#v", used)
  129. }
  130. time_left_seconds := dfc.Time_left * 60
  131. if time_left_seconds-int(left.Seconds()) > 1 {
  132. t.Errorf("Time Left differences > 1 second: test %#v door %#v", time_left_seconds, left)
  133. }
  134. if startDelta.Seconds() > 1 {
  135. t.Errorf("Start Time differences: test %#v door %#v delta %#v", start, d.StartTime, startDelta)
  136. }
  137. if timeoutDelta.Seconds() > 1 {
  138. t.Errorf("TimeOut differences: test %#v door %#v delta %#v", timeout, d.TimeOut, timeoutDelta)
  139. }
  140. }
  141. func TestDetectFail(t *testing.T) {
  142. tmpFile, err := os.CreateTemp("", "test-*")
  143. if err != nil {
  144. panic("Cannot create temporary file")
  145. }
  146. // Remember to clean up the file afterwards
  147. defer os.Remove(tmpFile.Name())
  148. // establish network socket connection to set Comm_handle
  149. server, client := setupSockets()
  150. // We're not testing closed connections, so:
  151. defer server.Close()
  152. defer client.Close()
  153. // Send nothing
  154. var fd int = socket_to_fd(client)
  155. defer close_fd(fd)
  156. // Create door32.sys file
  157. dfc := DropfileConfig{2, fd, 1800, "Test BBSID", 1701, "Real Username", "Handle", 880, 28, 0, 13}
  158. _, err = tmpFile.WriteString(fmt.Sprintf("%d\n%d\n%d\n%s\n%d\n%s\n%s\n%d\n%d\n%d\n%d\n",
  159. dfc.Comm_type, dfc.Comm_handle, dfc.Baudrate, dfc.BBSID, dfc.User_number, dfc.Real_name, dfc.Handle,
  160. dfc.Security_level, dfc.Time_left, dfc.Emulation, dfc.Node))
  161. if err != nil {
  162. t.Error("tmpFile.WriteString:", err)
  163. }
  164. err = tmpFile.Close()
  165. if err != nil {
  166. t.Error("tmpFile.Close:", err)
  167. }
  168. d := Door{ReaderCanClose: true}
  169. // Because we're not the only one calling door.Init(), the
  170. // door global variables might be from a previous test run.
  171. Unicode = false
  172. CP437 = false
  173. Full_CP437 = false
  174. Width = 0
  175. Height = 0
  176. // If I call d.Init() more then once flag complains about flag redefined.
  177. // Reset flags
  178. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
  179. // preset commandline args so door can init
  180. os.Args = []string{"door", "-d", tmpFile.Name()}
  181. d.Init("menu-test")
  182. t.Logf("Init completed.")
  183. defer d.Close()
  184. // clean up log file
  185. // I don't need to. Tests are run in /tmp/go-buildNNNN.
  186. // defer os.Remove("menu-test-13.log")
  187. if Unicode || CP437 {
  188. t.Errorf("Expected FALSE, got Unicode %t CP437 %t", Unicode, CP437)
  189. }
  190. if Width != 0 || Height != 0 {
  191. t.Errorf("Expected 0, 0, got Width %d, Height %d", Width, Height)
  192. }
  193. t.Logf("Closing server and client...")
  194. server.Close()
  195. client.Close()
  196. // time.Sleep(time.Duration(1) * time.Second)
  197. t.Logf("Done.")
  198. }
  199. // Pass d*Door to test. Otherwise we get a copy of the object passed!
  200. // go vet (shows this error/issue)
  201. // Generic tests that will be called from CP437 and Unicode routines
  202. func InputTests(t *testing.T, server net.Conn, d *Door, mode string) {
  203. var err error
  204. var buffer string
  205. keytest := map[string][]rune{
  206. "\x1b": []rune{0x1b},
  207. "\x0d\x00": []rune{0x0d},
  208. "\x0d\x0a": []rune{0x0d},
  209. "\x0dCQ": []rune{0x0d, 'C', 'Q'},
  210. "\x0dA": []rune{0x0d, 'A'},
  211. "\x0dCAT": []rune{0x0d, 'C', 'A', 'T'},
  212. "\U0001f920\u2615": []rune{'\U0001f920', '\u2615'},
  213. }
  214. /*
  215. Test input buffer processing.
  216. Create a string with unicode that doesn't fit into the
  217. entire read buffer. And build the proper response to match.
  218. */
  219. // x = number of missing bytes (from unicode symbol).
  220. for x := 1; x <= 3; x++ {
  221. tosend := strings.Repeat(" ", READ_SIZE-x) + "\U0001f920"
  222. receive := []rune(strings.Repeat(" ", READ_SIZE-x))
  223. receive = append(receive, '\U0001f920')
  224. keytest[tosend] = receive
  225. }
  226. keyextest := map[string][]Extended{
  227. "\x00\x50\x00\x48\x00\x4b\x00\x4d": []Extended{DOWN_ARROW, UP_ARROW, LEFT_ARROW, RIGHT_ARROW},
  228. "\x00\x47\x00\x4f\x00\x49\x00\x51": []Extended{HOME, END, PAGE_UP, PAGE_DOWN},
  229. "\x00\x3b\x00\x3c\x00\x3d\x00\x3e": []Extended{F1, F2, F3, F4},
  230. "\x00\x3f\x00\x40\x00\x41\x00\x42": []Extended{F5, F6, F7, F8},
  231. "\x00\x43\x00\x44\x00\x52\x00\x53": []Extended{F9, F10, INSERT, DELETE},
  232. "\x1b[A\x1b[B\x1b[C\x1b[D": []Extended{UP_ARROW, DOWN_ARROW, RIGHT_ARROW, LEFT_ARROW},
  233. "\x1b[H\x1b[F\x1b[K\x1b[V\x1b[U": []Extended{HOME, END, END, PAGE_UP, PAGE_DOWN},
  234. "\x1b[5~\x1b[6~": []Extended{PAGE_UP, PAGE_DOWN},
  235. "\x1b[@\x1b[2~\x1b[3~": []Extended{INSERT, INSERT, DELETE},
  236. "\x1bOP\x1bOQ\x1bOR\x1bOS": []Extended{F1, F2, F3, F4},
  237. "\x1b[15~\x1b[17~\x1b[18~\x1b[19~": []Extended{F5, F6, F7, F8},
  238. "\x1b[20~\x1b[21~\x1b[23~\x1b[24~": []Extended{F9, F10, F11, F12},
  239. }
  240. keyWait := time.Duration(50 * time.Millisecond)
  241. // Verify input is empty
  242. for {
  243. input, ex, err := d.WaitKey(keyWait)
  244. if err == nil {
  245. t.Errorf("Keys: %#v, %#v\n", input, ex)
  246. } else {
  247. break
  248. }
  249. }
  250. t.Logf("Starting keytest (%s)\n", mode)
  251. for send, get := range keytest {
  252. if VERBOSE_TEST {
  253. t.Logf("Sending %#v: Expect: %#v\n", send, get)
  254. }
  255. var buffer []byte = []byte(send)
  256. _, err = server.Write(buffer)
  257. if err != nil {
  258. t.Error("server.Write:", err)
  259. }
  260. time.Sleep(time.Millisecond)
  261. var recv []rune = make([]rune, 0)
  262. var retries int = 0
  263. for {
  264. input, _, err := d.WaitKey(keyWait)
  265. if VERBOSE_TEST {
  266. t.Logf(">> %#v, %#v\n", input, err)
  267. }
  268. if err == nil {
  269. recv = append(recv, input)
  270. if len(recv) != len(get) {
  271. continue
  272. }
  273. break
  274. } else {
  275. t.Logf("WaitKey Err: %#v\n", err)
  276. if len(recv) != len(get) {
  277. if retries < 5 {
  278. retries++
  279. t.Logf("Retry %d want %d got %d\n", retries, len(get), len(recv))
  280. continue
  281. }
  282. break
  283. }
  284. }
  285. }
  286. if len(recv) != len(get) {
  287. t.Errorf("FAILURE: Sent %#v, LEN expected %#v, got %#v", send, get, recv)
  288. } else {
  289. matches := true
  290. for idx, i := range get {
  291. if recv[idx] != i {
  292. matches = false
  293. break
  294. }
  295. }
  296. if !matches {
  297. t.Errorf("FAILURE: Sent %#v, MATCH expected %#v, got %#v", send, get, recv)
  298. } else {
  299. if VERBOSE_TEST {
  300. t.Logf("Success.")
  301. }
  302. }
  303. }
  304. }
  305. t.Logf("Starting keyextest (%s)\n", mode)
  306. for send, get := range keyextest {
  307. if VERBOSE_TEST {
  308. t.Logf("Sending %#v: Expect: %#v\n", send, get)
  309. }
  310. var buffer []byte = []byte(send)
  311. _, err = server.Write(buffer)
  312. if err != nil {
  313. t.Error("server.Write:", err)
  314. }
  315. time.Sleep(time.Millisecond)
  316. var recv []Extended = make([]Extended, 0)
  317. var retries int = 0
  318. for {
  319. _, ex, err := d.WaitKey(keyWait)
  320. if err == nil {
  321. recv = append(recv, ex)
  322. if len(recv) != len(get) {
  323. continue
  324. }
  325. break
  326. } else {
  327. t.Logf("WaitKey err: #%v\n", err)
  328. if len(recv) != len(get) {
  329. if retries < 5 {
  330. retries++
  331. t.Logf("Retry %d want %d got %d\n", retries, len(get), len(recv))
  332. continue
  333. }
  334. break
  335. }
  336. }
  337. }
  338. if len(recv) != len(get) {
  339. t.Errorf("Sent %#v, LEN expected %#v, got %#v", send, get, recv)
  340. } else {
  341. matches := true
  342. for idx, i := range get {
  343. if recv[idx] != i {
  344. matches = false
  345. break
  346. }
  347. }
  348. if !matches {
  349. t.Errorf("Sent %#v, MATCH expected %#v, got %#v", send, get, recv)
  350. }
  351. }
  352. }
  353. clear_socket(server, t)
  354. t.Logf("Starting WaitKey timeout (%s)...\n", mode)
  355. _, _, timeout := d.WaitKey(keyWait)
  356. if timeout == nil {
  357. t.Errorf("Expected timeout, got %d / %X", timeout, timeout)
  358. } else {
  359. t.Logf("Ok! Buffer should be empty! -1 (timeout)")
  360. }
  361. t.Logf("Starting input test (%s)\n", mode)
  362. // Input test
  363. buffer = "1234567890\r"
  364. _, err = server.Write([]byte(buffer))
  365. if err != nil {
  366. t.Error("server.Write:", err)
  367. }
  368. time.Sleep(time.Millisecond)
  369. var input string = d.Input(5)
  370. if input != "12345" {
  371. t.Errorf("Expected Input(5) = 12345, but got %#v", input)
  372. }
  373. // read everything
  374. var result string = clear_socket(server, t)
  375. expected := " \x08\x08\x08\x08\x0812345\x07\x07\x07\x07"
  376. if result != expected {
  377. expected = " \x08\x08\x08\x08\x0812345\x07\x07\x07\x07\x07"
  378. if result != expected {
  379. t.Errorf("Buffer Input(5): Expected %#v, got %#v\n", expected, result)
  380. }
  381. }
  382. err = server.SetReadDeadline(time.Time{})
  383. if err != nil {
  384. t.Error("server.SetReadDeadLine:", err)
  385. }
  386. buffer = "12345678\x08\x089\r"
  387. _, err = server.Write([]byte(buffer))
  388. if err != nil {
  389. t.Error("server.Write:", err)
  390. }
  391. time.Sleep(time.Millisecond)
  392. input = d.Input(5)
  393. if input != "1239" {
  394. t.Errorf("Expected Input(5) = 1239, but got %#v", input)
  395. }
  396. buffer = "12\x08\x08\x08987\x00\x48654321\r"
  397. _, err = server.Write([]byte(buffer))
  398. if err != nil {
  399. t.Error("server.Write:", err)
  400. }
  401. time.Sleep(time.Millisecond)
  402. input = d.Input(5)
  403. if input != "98765" {
  404. t.Errorf("Expected Input(5) = 98765, but got %#v", input)
  405. }
  406. t.Logf("Starting cursor pos test (%s)\n", mode)
  407. var cpos []CursorPos = []CursorPos{{1, 1}, {50, 5}, {4, 40}, {80, 25}, {160, 55}}
  408. for _, pos := range cpos {
  409. if VERBOSE_TEST {
  410. t.Logf("Sending CursorPos(%d,%d)\n", pos.X, pos.Y)
  411. }
  412. buffer = CursorReply(pos)
  413. _, err := server.Write([]byte(buffer))
  414. if err != nil {
  415. t.Error("server.Write:", err)
  416. }
  417. }
  418. for _, pos := range cpos {
  419. _, ex, err := d.WaitKey(keyWait)
  420. if err != nil {
  421. t.Error("WaitKey:", err)
  422. continue
  423. }
  424. if ex != CURSOR {
  425. t.Errorf("Expected Extended = CURSOR (was %s)", ex.String())
  426. continue
  427. }
  428. cp, ok := d.GetCursorPos()
  429. if !ok {
  430. t.Error("Extended sent CURSOR, but GetCursorPos failed.")
  431. continue
  432. }
  433. if (cp.X != pos.X) || (cp.Y != pos.Y) {
  434. t.Errorf("Expected (%d,%d), Got (%d,%d)", pos.X, pos.Y, cp.X, cp.Y)
  435. }
  436. }
  437. t.Logf("Starting Mouse test (%s)\n", mode)
  438. var mouse []Mouse = []Mouse{{1, 4, 5}, {4, 4, 5}, {45, 80, 25}, {2, 55, 17}}
  439. for _, m := range mouse {
  440. if VERBOSE_TEST {
  441. t.Logf("Sending Mouse(%d @ %d,%d)\n", m.Button, m.X, m.Y)
  442. }
  443. buffer = MouseReply(m)
  444. _, err = server.Write([]byte(buffer))
  445. if err != nil {
  446. t.Error("server.Write:", err)
  447. }
  448. }
  449. for _, pos := range mouse {
  450. _, ex, err := d.WaitKey(keyWait)
  451. if err != nil {
  452. t.Error("WaitKey:", err)
  453. continue
  454. }
  455. if ex != MOUSE {
  456. t.Errorf("Expected Extended = MOUSE (was %s)", ex.String())
  457. continue
  458. }
  459. mpos, ok := d.GetMouse()
  460. if !ok {
  461. t.Error("Extended sent MOUSE, but GetMouse failed.")
  462. continue
  463. }
  464. if (pos.Button != mpos.Button) || (pos.X != mpos.X) || (pos.Y != mpos.Y) {
  465. t.Errorf("Expected (%d @ %d, %d), Got (%d @ %d, %d)",
  466. pos.Button, pos.X, pos.Y, mpos.Button, mpos.X, mpos.Y)
  467. }
  468. }
  469. }
  470. func TestDoorCP437(t *testing.T) {
  471. var tmpFile *os.File
  472. var err error
  473. // Dropfile
  474. tmpFile, err = os.CreateTemp("", "test-*")
  475. if err != nil {
  476. panic("Cannot create temporary file")
  477. }
  478. defer os.Remove(tmpFile.Name())
  479. // establish network socket connection to set Comm_handle
  480. var server, client net.Conn
  481. server, client = setupSockets()
  482. // Ok, we have a server socket, and the client socket (that the door would talk to)
  483. // CP437 80x25 response
  484. buffer := CP437WidthHeight(80, 25)
  485. _, err = server.Write([]byte(buffer))
  486. if err != nil {
  487. t.Error("server.Write:", err)
  488. }
  489. time.Sleep(time.Millisecond)
  490. // Access Fd (File descriptor) of client for dropfile
  491. var fd int = socket_to_fd(client)
  492. defer close_fd(fd)
  493. // Create door32.sys file
  494. var node int = 10
  495. dfc := DropfileConfig{2, fd, 1800, "Test BBSID", 1701, "Real Username", "Handle", 880, 28, 0, node}
  496. _, err = tmpFile.WriteString(fmt.Sprintf("%d\n%d\n%d\n%s\n%d\n%s\n%s\n%d\n%d\n%d\n%d\n",
  497. dfc.Comm_type, dfc.Comm_handle, dfc.Baudrate, dfc.BBSID, dfc.User_number, dfc.Real_name, dfc.Handle,
  498. dfc.Security_level, dfc.Time_left, dfc.Emulation, dfc.Node))
  499. if err != nil {
  500. t.Error("tmpFile.WriteString:", err)
  501. }
  502. err = tmpFile.Close()
  503. if err != nil {
  504. t.Error("tmpFile.Close:", err)
  505. }
  506. d := Door{} // Deprecated: ReaderCanClose: true}
  507. // Because we're not the only one calling door.Init(), the
  508. // door global variables might be from a previous test run.
  509. // Reset back to defaults.
  510. Unicode = false
  511. CP437 = false
  512. Full_CP437 = false
  513. Width = 0
  514. Height = 0
  515. // If I call d.Init() more then once flag complains about flag redefined.
  516. // Reset flags
  517. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
  518. // preset commandline args so door can init
  519. os.Args = []string{"door", "-d", tmpFile.Name()}
  520. d.Init("input-test")
  521. defer d.Close()
  522. // clean up logfile - (filename is from Init name + node #)
  523. if !KEEP_LOGS {
  524. defer os.Remove(fmt.Sprintf("input-test-%d.log", node))
  525. }
  526. if VERBOSE_TEST {
  527. t.Logf("Verify Unicode %dX%d\n", 80, 25)
  528. }
  529. // Ok!
  530. if Unicode {
  531. t.Errorf("Unicode is %t", Unicode)
  532. }
  533. if !CP437 {
  534. t.Errorf("Expect CP437 true, is %t", CP437)
  535. }
  536. if Width != 80 {
  537. t.Errorf("Width not 80: %d", Width)
  538. }
  539. if Height != 25 {
  540. t.Errorf("Height not 25: %d", Height)
  541. }
  542. clear_socket(server, t)
  543. InputTests(t, server, &d, "CP437")
  544. t.Logf("server close")
  545. log.Println("server close")
  546. server.Close()
  547. time.Sleep(time.Millisecond)
  548. keyWait := time.Duration(50 * time.Millisecond)
  549. _, _, err = d.WaitKey(keyWait)
  550. if err != ErrDisconnected {
  551. t.Errorf("Expected ErrDisconnected, got %#v", err)
  552. }
  553. if !d.Disconnect() {
  554. t.Errorf("Disconnected flag shows: %t (should be true)", d.Disconnect())
  555. }
  556. _, _, err = d.WaitKey(time.Millisecond)
  557. if err != ErrDisconnected {
  558. t.Errorf("Expected ErrDisconnected, got %#v", err)
  559. }
  560. t.Logf("client close")
  561. client.Close()
  562. time.Sleep(time.Millisecond)
  563. t.Logf("Input on closed server and client")
  564. var blank string = d.Input(5)
  565. if blank != "" {
  566. t.Errorf("Input should return blank (hangup).")
  567. }
  568. _, _, err = d.WaitKey(time.Millisecond)
  569. if err != ErrDisconnected {
  570. t.Errorf("Expected ErrDisconnected, got %#v", err)
  571. }
  572. d.Write("\x00")
  573. time.Sleep(time.Millisecond)
  574. }
  575. func TestDoorUnicode(t *testing.T) {
  576. var tmpFile *os.File
  577. var err error
  578. // Dropfile
  579. tmpFile, err = os.CreateTemp("", "test-*")
  580. if err != nil {
  581. panic("Cannot create temporary file")
  582. }
  583. defer os.Remove(tmpFile.Name())
  584. // establish network socket connection to set Comm_handle
  585. var server, client net.Conn
  586. server, client = setupSockets()
  587. // Ok, we have a server socket, and the client socket (that the door would talk to)
  588. // unicode 190x43 response
  589. buffer := UnicodeWidthHeight(190, 43)
  590. _, err = server.Write([]byte(buffer))
  591. if err != nil {
  592. t.Error("server.Write:", err)
  593. }
  594. time.Sleep(time.Millisecond)
  595. // Access Fd (File descriptor) of client for dropfile
  596. var fd int = socket_to_fd(client)
  597. defer close_fd(fd)
  598. // Create door32.sys file
  599. var node int = 11
  600. dfc := DropfileConfig{2, fd, 1800, "Test BBSID", 1701, "Real Username", "Handle", 880, 28, 0, node}
  601. _, err = tmpFile.WriteString(fmt.Sprintf("%d\n%d\n%d\n%s\n%d\n%s\n%s\n%d\n%d\n%d\n%d\n",
  602. dfc.Comm_type, dfc.Comm_handle, dfc.Baudrate, dfc.BBSID, dfc.User_number, dfc.Real_name, dfc.Handle,
  603. dfc.Security_level, dfc.Time_left, dfc.Emulation, dfc.Node))
  604. if err != nil {
  605. t.Error("tmpFile.WriteString:", err)
  606. }
  607. err = tmpFile.Close()
  608. if err != nil {
  609. t.Error("tmpFile.Close:", err)
  610. }
  611. d := Door{} // Deprecated: ReaderCanClose: true}
  612. // Because we're not the only one calling door.Init(), the
  613. // door global variables might be from a previous test run.
  614. // Reset back to defaults.
  615. Unicode = false
  616. CP437 = false
  617. Full_CP437 = false
  618. Width = 0
  619. Height = 0
  620. // If I call d.Init() more then once flag complains about flag redefined.
  621. // Reset flags
  622. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError)
  623. // preset commandline args so door can init
  624. os.Args = []string{"door", "-d", tmpFile.Name()}
  625. d.Init("input-test")
  626. defer d.Close()
  627. // clean up logfile - (filename is from Init name + node #)
  628. if !KEEP_LOGS {
  629. defer os.Remove(fmt.Sprintf("input-test-%d.log", node))
  630. }
  631. // Ok!
  632. if !Unicode {
  633. t.Errorf("Unicode not true %t", Unicode)
  634. }
  635. if Width != 190 {
  636. t.Errorf("Width not 190: %d", Width)
  637. }
  638. if Height != 43 {
  639. t.Errorf("Height not 43: %d", Height)
  640. }
  641. clear_socket(server, t)
  642. keyWait := time.Duration(50 * time.Millisecond)
  643. InputTests(t, server, &d, "Unicode")
  644. buffer = "\U0001f9201234\r"
  645. // double wide (2) + 4 = 6, we're inputting 5.
  646. _, err = server.Write([]byte(buffer))
  647. if err != nil {
  648. t.Error("server.Write:", err)
  649. }
  650. time.Sleep(time.Millisecond)
  651. // Unicode mode can handle unicode input. CP437 mode can't -- really.
  652. input := d.Input(5)
  653. expect := "\U0001f920123"
  654. if input != expect {
  655. t.Errorf("Expected Input(5) = %#v, but got %#v", expect, input)
  656. }
  657. clear_socket(server, t)
  658. t.Logf("server close")
  659. log.Println("server close")
  660. server.Close()
  661. time.Sleep(time.Millisecond)
  662. _, _, err = d.WaitKey(keyWait)
  663. if err != ErrDisconnected {
  664. t.Errorf("Expected ErrDisconnected, got %#v", err)
  665. }
  666. if !d.Disconnect() {
  667. t.Errorf("Disconnected flag shows: %t (should be true)", d.Disconnect())
  668. }
  669. _, _, err = d.WaitKey(time.Millisecond)
  670. if err != ErrDisconnected {
  671. t.Errorf("Expected ErrDisconnected, got %#v", err)
  672. }
  673. t.Logf("client close")
  674. client.Close()
  675. time.Sleep(time.Millisecond)
  676. t.Logf("Input on closed server and client")
  677. var blank string = d.Input(5)
  678. if blank != "" {
  679. t.Errorf("Input should return blank (hangup).")
  680. }
  681. _, _, err = d.WaitKey(time.Millisecond)
  682. if err != ErrDisconnected {
  683. t.Errorf("Expected ErrDisconnected, got %#v", err)
  684. }
  685. d.Write("\x00")
  686. time.Sleep(time.Millisecond)
  687. }