pack_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * ECAL
  3. *
  4. * Copyright 2020 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package tool
  11. import (
  12. "bytes"
  13. "flag"
  14. "fmt"
  15. "io/ioutil"
  16. "os"
  17. "path/filepath"
  18. "strings"
  19. "testing"
  20. "devt.de/krotik/common/errorutil"
  21. "devt.de/krotik/common/fileutil"
  22. "devt.de/krotik/common/stringutil"
  23. )
  24. const packTestDir = "packtest"
  25. var testPackOut *bytes.Buffer
  26. var lastReturnCode = 0
  27. var lastRuntimeError error
  28. func setupPackTestDir() {
  29. if res, _ := fileutil.PathExists(packTestDir); res {
  30. os.RemoveAll(packTestDir)
  31. }
  32. err := os.Mkdir(packTestDir, 0770)
  33. if err != nil {
  34. fmt.Print("Could not create test directory:", err.Error())
  35. os.Exit(1)
  36. }
  37. err = os.Mkdir(filepath.Join(packTestDir, "sub"), 0770)
  38. if err != nil {
  39. fmt.Print("Could not create test directory:", err.Error())
  40. os.Exit(1)
  41. }
  42. osExit = func(code int) {
  43. lastReturnCode = code
  44. }
  45. handleError = func(err error) {
  46. lastRuntimeError = err
  47. }
  48. }
  49. func tearDownPackTestDir() {
  50. err := os.RemoveAll(packTestDir)
  51. if err != nil {
  52. fmt.Print("Could not remove test directory:", err.Error())
  53. }
  54. }
  55. func newTestCLIPacker() *CLIPacker {
  56. clip := NewCLIPacker()
  57. testPackOut = &bytes.Buffer{}
  58. clip.LogOut = testPackOut
  59. return clip
  60. }
  61. func TestPackParseArgs(t *testing.T) {
  62. setupPackTestDir()
  63. defer tearDownPackTestDir()
  64. clip := newTestCLIPacker()
  65. packTestSrcBin := filepath.Join(packTestDir, "source.bin")
  66. out := bytes.Buffer{}
  67. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) // Reset CLI parsing
  68. flag.CommandLine.SetOutput(&out)
  69. osArgs = []string{packTestSrcBin, "foo", "-help"}
  70. if ok := clip.ParseArgs(); !ok {
  71. t.Error("Asking for help should ask to finish the program")
  72. return
  73. }
  74. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) // Reset CLI parsing
  75. flag.CommandLine.SetOutput(&out)
  76. osArgs = []string{packTestSrcBin, "foo", "-help"}
  77. if err := clip.Pack(); err != nil {
  78. t.Error("Unexpected result:", err)
  79. return
  80. }
  81. if !strings.Contains(out.String(), "Root directory for ECAL interpreter") {
  82. t.Error("Unexpected output:", out.String())
  83. return
  84. }
  85. out = bytes.Buffer{}
  86. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) // Reset CLI parsing
  87. flag.CommandLine.SetOutput(&out)
  88. osArgs = []string{packTestSrcBin, "foo", "myentryfile"}
  89. if ok := clip.ParseArgs(); ok {
  90. t.Error("Only asking for help should finish the program")
  91. return
  92. }
  93. if ok := clip.ParseArgs(); ok {
  94. t.Error("Only asking for help should finish the program")
  95. return
  96. }
  97. if clip.EntryFile != "myentryfile" {
  98. t.Error("Unexpected output:", clip.EntryFile)
  99. return
  100. }
  101. }
  102. func TestPackPacking(t *testing.T) {
  103. setupPackTestDir()
  104. defer tearDownPackTestDir()
  105. clip := newTestCLIPacker()
  106. packTestSrcBin := filepath.Join(packTestDir, "source.bin")
  107. packTestEntry := filepath.Join(packTestDir, "myentry.ecal")
  108. packAnotherFile := filepath.Join(packTestDir, "sub", "anotherfile.ecal")
  109. packTestDestBin := filepath.Join(packTestDir, "dest.exe")
  110. b1 = 5
  111. b2 = len(packmarker) + 11
  112. err := ioutil.WriteFile(packTestSrcBin, []byte("mybinaryfilecontent#somemorecontent"+
  113. stringutil.GenerateRollingString("123", 30)), 0777)
  114. errorutil.AssertOk(err)
  115. err = ioutil.WriteFile(packTestEntry, []byte("myvar := 1; 5"), 0777)
  116. errorutil.AssertOk(err)
  117. err = ioutil.WriteFile(packAnotherFile, []byte("func f() { raise(123) };f()"), 0777)
  118. errorutil.AssertOk(err)
  119. out := bytes.Buffer{}
  120. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) // Reset CLI parsing
  121. flag.CommandLine.SetOutput(&out)
  122. // Write a binary with return code
  123. osArgs = []string{packTestSrcBin, "foo", "-dir", packTestDir, "-target",
  124. packTestDestBin, packTestEntry}
  125. // Simulate that whitespaces are added around the pack marker
  126. oldpackmarker := packmarker
  127. packmarker = fmt.Sprintf("\n\n\n%v\n\n\n", packmarker)
  128. if err := clip.Pack(); err != nil {
  129. t.Error("Unexpected result:", err)
  130. return
  131. }
  132. packmarker = oldpackmarker
  133. if !strings.Contains(testPackOut.String(), "bytes for intro") {
  134. t.Error("Unexpected output:", testPackOut.String())
  135. return
  136. }
  137. // Write a binary with which errors
  138. clip = newTestCLIPacker()
  139. out = bytes.Buffer{}
  140. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) // Reset CLI parsing
  141. flag.CommandLine.SetOutput(&out)
  142. osArgs = []string{packTestSrcBin, "foo", "-dir", packTestDir, "-target",
  143. packTestDestBin + ".error", packAnotherFile}
  144. if err := clip.Pack(); err != nil {
  145. t.Error("Unexpected result:", err)
  146. return
  147. }
  148. if !strings.Contains(testPackOut.String(), "bytes for intro") {
  149. t.Error("Unexpected output:", testPackOut.String())
  150. return
  151. }
  152. // Write also a corrupted binary
  153. err = ioutil.WriteFile(packTestDestBin+".corrupted", []byte(
  154. "mybinaryfilecontent#somemorecontent"+
  155. stringutil.GenerateRollingString("123", 30)+
  156. "\n"+
  157. packmarker+
  158. "\n"+
  159. stringutil.GenerateRollingString("123", 30)), 0777)
  160. errorutil.AssertOk(err)
  161. testRunningPackedBinary(t)
  162. }
  163. func testRunningPackedBinary(t *testing.T) {
  164. packTestDestBin := filepath.Join(packTestDir, "dest") // Suffix .exe should be appended
  165. out := bytes.Buffer{}
  166. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) // Reset CLI parsing
  167. flag.CommandLine.SetOutput(&out)
  168. osArgs = []string{packTestDestBin + ".exe.corrupted"}
  169. RunPackedBinary()
  170. if lastRuntimeError == nil || lastRuntimeError.Error() != "zip: not a valid zip file" {
  171. t.Error("Unexpected result:", lastRuntimeError)
  172. return
  173. }
  174. out = bytes.Buffer{}
  175. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) // Reset CLI parsing
  176. flag.CommandLine.SetOutput(&out)
  177. osArgs = []string{packTestDestBin}
  178. RunPackedBinary()
  179. if lastRuntimeError != nil {
  180. t.Error("Unexpected result:", lastRuntimeError)
  181. return
  182. }
  183. if lastReturnCode != 5 {
  184. t.Error("Unexpected result:", lastReturnCode)
  185. return
  186. }
  187. out = bytes.Buffer{}
  188. flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError) // Reset CLI parsing
  189. flag.CommandLine.SetOutput(&out)
  190. osStderr = &out
  191. osArgs = []string{packTestDestBin + ".exe.error"}
  192. RunPackedBinary()
  193. if lastRuntimeError != nil {
  194. t.Error("Unexpected result:", lastRuntimeError)
  195. return
  196. }
  197. if !strings.HasPrefix(out.String(), "ECAL error in packtest/dest.exe.error: 123 () (Line:1 Pos:12)") ||
  198. !strings.Contains(out.String(), "raise(123)") {
  199. t.Error("Unexpected result:", out.String())
  200. return
  201. }
  202. }