Guest User

Untitled

a guest
Jul 19th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.92 KB | None | 0 0
  1. sys = require 'sys'
  2. {spawn} = require 'child_process'
  3. fs = require 'fs'
  4. path = require 'path'
  5. EventEmitter = require('events').EventEmitter
  6.  
  7. Utils = require './utils'
  8.  
  9. erlangPath = path.normalize("#{__dirname}/../erl_src")
  10. tempPath = path.normalize("#{process.cwd()}/.riaktest")
  11.  
  12. # Ported from the Ruby riak-client
  13. class TestServer extends EventEmitter
  14. @defaults =
  15. appConfig:
  16. riak_core:
  17. web_ip: "127.0.0.1"
  18. web_port: 9000
  19. handoff_port: 9001
  20. ring_creation_size: 64
  21. riak_kv:
  22. storage_backend: {atom: "riak_kv_test_backend"}
  23. pb_ip: "127.0.0.1"
  24. pb_port: 9002
  25. js_vm_count: 8
  26. js_max_vm_mem: 8
  27. js_thread_stack: 16
  28. riak_kv_stat: true
  29. luwak:
  30. enabled: false
  31. sasl:
  32. errlog_type: {atom: "error"}
  33. vmArgs:
  34. "-name": "riaktest#{Math.floor(Math.random()*100000000000)}@127.0.0.1"
  35. "-setcookie": "riak-js-test"
  36. "+K": true
  37. "+A": 64
  38. "-smp": "enable"
  39. "-env ERL_MAX_PORTS": 4096
  40. "-env ERL_FULLSWEEP_AFTER": 0
  41. "-pa": erlangPath
  42. tempDir: tempPath
  43.  
  44. constructor: (options) ->
  45. @options = Utils.mixin true, {}, TestServer.defaults, options
  46. @options.appConfig.riak_core.ring_state_dir = "#{@options.tempDir}/data/ring"
  47. @options.binDir = path.normalize(@options.binDir)
  48. @erlangPrompt = new RegExp("^.#{@options.vmArgs['-name']}.\\d+>", "m")
  49.  
  50. prepare: (callback) ->
  51. unless @prepared?
  52. @createTempDirectories =>
  53. @riakScript = "#{@temp_bin}/riak"
  54. @writeRiakScript =>
  55. @writeVmArgs =>
  56. @writeAppConfig =>
  57. @prepared = true
  58. callback() if callback
  59.  
  60. start: (callback) ->
  61. if @prepared and not @started and @listeners('erlangPrompt').length is 0
  62. setStarted = =>
  63. @started = true
  64. callback() if callback
  65.  
  66. @once 'erlangPrompt', setStarted
  67. @console = spawn(@riakScript, ["console"])
  68. @console.on 'exit', @registerStop
  69.  
  70. @console.stdout.setEncoding("ascii")
  71. @console.stderr.setEncoding("ascii")
  72.  
  73. # do the work of what we get from expect() in Ruby
  74. @console.stdout.on 'data', (data) =>
  75. unless data.search(@erlangPrompt) is -1
  76. @emit('erlangPrompt')
  77.  
  78. if @options.debug
  79. @console.stderr.on 'data', sys.debug
  80. @console.stdout.on 'data', sys.debug
  81.  
  82. process.on 'exit', =>
  83. @console.kill('SIGKILL')
  84. @registerStop()
  85.  
  86. stop: ->
  87. if @started and @listeners('erlangPrompt').length is 0
  88. @console.stdin.write("init:stop().\n", "ascii")
  89.  
  90. clear: (callback) ->
  91. if @started and @listeners('erlangPrompt').length is 0
  92. setStarted = =>
  93. @started = true
  94. callback() if callback
  95. sendReset = =>
  96. @once 'erlangPrompt', setStarted
  97. @started = false
  98. @console.stdin.write("riak_kv_test_backend:reset().\n", "ascii")
  99. @once 'erlangPrompt', sendReset
  100. @console.stdin.write("ok.\n", "ascii")
  101.  
  102. registerStop: ->
  103. @removeAllListeners('erlangPrompt')
  104. delete @console
  105. @started = false
  106.  
  107. createTempDirectories: (callback) ->
  108. subdirs = for dir in ['bin', 'etc', 'log', 'data', 'data/ring', 'pipe']
  109. this["temp_#{dir}"] = path.normalize("#{@options.tempDir}/#{dir}")
  110. subdirs.unshift @options.tempDir
  111. createDir = =>
  112. if subdirs.length is 0
  113. callback()
  114. else
  115. currDir = subdirs.shift()
  116. fs.mkdir currDir, 0700, createDir
  117. rmrf = spawn("rm", ["-rf", @options.tempDir])
  118. rmrf.on 'exit', createDir
  119.  
  120. writeRiakScript: (callback) ->
  121. outScript = fs.createWriteStream @riakScript, {encoding: 'utf8', mode: 0700}
  122. inScript = fs.createReadStream "#{@options.binDir}/riak", encoding: 'utf8'
  123.  
  124. inScript.on 'error', (err) ->
  125. sys.debug "error reading from #{inScript.path}:\n#{sys.inspect(err, true, null)}"
  126. throw err
  127. outScript.on 'error', (err) ->
  128. sys.debug "error writing to #{outScript.path} script:\n#{sys.inspect(err, true, null)}"
  129. throw err
  130.  
  131. outScript.on 'drain', -> inScript.resume()
  132.  
  133. inScript.on 'data', (data) =>
  134. data = data.toString('utf8') if Buffer.isBuffer(data)
  135. data = data.replace(/(RUNNER_SCRIPT_DIR=)(.*)$/m, "$1#{@temp_bin}")
  136. data = data.replace(/(RUNNER_ETC_DIR=)(.*)$/m, "$1#{@temp_etc}")
  137. data = data.replace(/(RUNNER_USER=)(.*)$/m, "$1")
  138. data = data.replace(/(RUNNER_LOG_DIR=)(.*)$/m, "$1#{@temp_log}")
  139. data = data.replace(/(PIPE_DIR=)(.*)$/m, "$1#{@temp_pipe}")
  140. data = data.replace("RUNNER_BASE_DIR=${RUNNER_SCRIPT_DIR%/*}", "RUNNER_BASE_DIR=#{path.normalize(@options.binDir + '/..')}")
  141. outScript.write data
  142. inScript.pause()
  143.  
  144. inScript.on 'end', ->
  145. outScript.end()
  146. callback() if callback
  147.  
  148. writeVmArgs: (callback) ->
  149. vmArgs = for own option, value of @options.vmArgs
  150. "#{option} #{value}"
  151.  
  152. vmArgs = vmArgs.join("\n")
  153. fs.writeFile("#{@temp_etc}/vm.args", vmArgs, callback)
  154.  
  155. writeAppConfig: (callback) ->
  156. appConfig = @toErlangConfig(@options.appConfig) + "."
  157. fs.writeFile("#{@temp_etc}/app.config", appConfig, callback)
  158.  
  159. # Converts an object into app.config-compatible Erlang terms
  160. toErlangConfig: (object, depth = 1) ->
  161. padding = (' ' for num in [1..depth]).join ""
  162.  
  163. parentPadding = if depth <= 1
  164. ''
  165. else
  166. (' ' for num in [1..(depth-1)]).join ""
  167.  
  168. values = for own key, value of object
  169. if value.atom?
  170. printable = value.atom
  171. else if typeof value is 'string'
  172. printable = "\"#{value}\""
  173. else if value instanceof Object
  174. printable = @toErlangConfig(value, depth+1)
  175. else
  176. printable = value.toString()
  177. "{#{key}, #{printable}}"
  178.  
  179. values = values.join(",\n#{padding}")
  180.  
  181. "[\n#{padding}#{values}\n#{parentPadding}]"
  182.  
  183. # Node v0.2.6 doesn't have EventEmitter.once
  184. once: (type, listener) ->
  185. callback = =>
  186. @removeListener(type, callback)
  187. listener.apply(this, arguments)
  188. @on type, callback
  189. this
  190.  
  191. module.exports = TestServer
Add Comment
Please, Sign In to add comment