Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/testing_with_timidity' into develop
- Loading branch information
Showing
9 changed files
with
266 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ rvm: | |
before_install: | ||
- sudo apt-get update | ||
- sudo apt-get install libasound2-dev | ||
- sudo apt-get install timidity |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,4 +21,5 @@ end | |
group :testing do | ||
gem 'rspec' | ||
gem 'rake' | ||
gem 'ruby-ogginfo' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Jarvis Testing | ||
|
||
This is where all of the Jarvis tests and testing framework lives. There are a | ||
number of files that will help support writing new tests, including RSpec shared | ||
contexts and rake tasks. | ||
|
||
## Running Tests | ||
|
||
Tests are run using the standard rake command: | ||
|
||
$ rake | ||
|
||
This will fire off an RSpec testing suite with the command line options -cfs | ||
(coloured output and specdoc format). | ||
|
||
## Shared Contexts | ||
|
||
Jarvis has two (technically three but two are usually used in conjunction with | ||
each other) shared contexts that help with testing. | ||
|
||
### "server" and "timidity" | ||
|
||
This context is aimed at making writing tests that communicate with an external | ||
Jarvis process really, really easy. | ||
|
||
If you include these lines (in this order) in your RSpec describe block: | ||
|
||
include_context 'timidity' | ||
include_context 'server' | ||
|
||
You will get given a variety of helper methods and some before and after hooks | ||
will automatically run for you. First, a timidity server will be run in the | ||
background. It won't make any sound, instead it will output everything to an Ogg | ||
Vorbis file. This ogg file can be accessed using the `test_ogg` helper method. | ||
|
||
The `ogginfo` gem is used to extract information about the ogg file. | ||
Documentation for `ogginfo` can be found | ||
[here](https://github.com/moumar/ruby-ogginfo). If `test_ogg` returns nil it | ||
means that either the ogg file does not exist or timidity never wrote to it, | ||
which indicates that communication between Jarvis and timidity is not working. | ||
|
||
When timidity is up and running, a Jarvis process will be spawned. There are | ||
calls to `sleep` involved in booting Jarvis and timidity to give them time to | ||
load up. | ||
|
||
When both of these are running, the content of your test is run. There are two | ||
very useful helper methods that will aid in your test writing: `send_command` | ||
and `last_response`. Both of them are quite self explanatory. `send_command` | ||
will take a string and send it to the server and return the server response. | ||
`last_response` is a way of accessing that response numerous times. | ||
|
||
Here's an example: | ||
|
||
``` ruby | ||
describe "Server" do | ||
it "should respond to start" do | ||
send_command "start" | ||
last_response.should include('successfully') | ||
end | ||
end | ||
``` | ||
|
||
When your test has finished executing the Jarvis and timidity processes will be | ||
killed. | ||
|
||
**Note:** This context is quite noisy. All of the server boot up logs are put | ||
into stdout for debugging purposes (in case something goes wrong, you will want | ||
to look at the server logs). Test output is often very busy with this context. | ||
|
||
### test_server | ||
|
||
The "test_server" context will give you exactly the same `send_command` and | ||
`last_response` helper methods as the "server" context described above, but it | ||
will not spawn external processes. | ||
|
||
This context will monkey patch the MusicServer class so that it does not try and | ||
send any data to clients. Instead, it stores that data and makes it accessible | ||
through the `last_response` helper. | ||
|
||
Tests written with this context will look almost exactly the same as tests | ||
written with the "server" context. The only difference is that there is no | ||
timidity server running and, therefore, no ogg file to test against. This | ||
context is just for doing granular tests against the server object that doesn't | ||
require any interprocess communication. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,53 @@ | ||
require 'socket' | ||
|
||
shared_context 'server' do | ||
# Helper method to send a command to the Jarvis server. | ||
@@jarvis_host = 'localhost' | ||
@@jarvis_port = 1337 | ||
|
||
# Starts up the external jarvis process and waits for it to boot. Then it | ||
# initiates a connection to the jarvis process under the @@socket variable. | ||
# | ||
# Commands can be sent to this jarvis instance with the send_command method. | ||
def start_jarvis | ||
@@jarvis_pid = fork do | ||
exec "#{Jarvis::ROOTDIR}/bin/jarvis" | ||
end | ||
|
||
sleep(1) | ||
@@socket = TCPSocket.new @@jarvis_host, @@jarvis_port | ||
end | ||
|
||
# Sends a command to the jarvis server that's running and returns the string | ||
# response from the server. | ||
def send_command command | ||
@jarvis.receive_data command | ||
@last_response = @jarvis.sent_data.last | ||
@@socket.print command | ||
@@last_response = @@socket.recv 4096 | ||
end | ||
|
||
# Helper method to check the value of the last command sent. | ||
# Refers to the response from the last command sent to jarvis. | ||
def last_response | ||
@last_response | ||
@@last_response | ||
end | ||
|
||
before :each do | ||
# Set option defaults and override testing to true | ||
Jarvis.options = Jarvis.option_defaults | ||
Jarvis.options[:logfile] = '/dev/null' | ||
Jarvis.options[:testing] = true | ||
Jarvis.log = Jarvis.default_logger | ||
# Stops the external jarvis process and closes the socket connection to it. | ||
def stop_jarvis | ||
if @@jarvis_pid | ||
@@socket.close if @@socket | ||
Process.kill('SIGINT', @@jarvis_pid) | ||
Process.wait(@@jarvis_pid) | ||
@@jarvis_pid = nil | ||
end | ||
end | ||
|
||
# Reset the commands array. This stops duplicate command errors. | ||
Jarvis::Command.reset | ||
|
||
@jarvis = Jarvis::MusicServer.new nil | ||
# RSpec hook to start jarvis before every test case in this context. | ||
before :each do | ||
@last_response = nil | ||
start_jarvis | ||
end | ||
|
||
# RSpec hook to stop jarvis after every test case in this context. | ||
after :each do | ||
@jarvis.unbind | ||
@jarvis = nil | ||
stop_jarvis | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# This shared context sets up all of the appropriate methods and monkey patches | ||
# that are needed to create and use a MusicServer object without running it | ||
# through EventMachine. | ||
|
||
# Because we aren't running the server inside event machine, we need to override | ||
# the send_data method and keep track of the data that has been sent in the | ||
# current request. | ||
class Jarvis::MusicServer | ||
def sent_data | ||
@sent_data ||= [] | ||
end | ||
|
||
def send_data data | ||
sent_data << data.to_s | ||
end | ||
end | ||
|
||
shared_context 'test_server' do | ||
# Helper method to send a command to the Jarvis server. | ||
def send_command command | ||
@jarvis.receive_data command | ||
@last_response = @jarvis.sent_data.last | ||
end | ||
|
||
# Helper method to check the value of the last command sent. | ||
def last_response | ||
@last_response | ||
end | ||
|
||
before :each do | ||
# Set option defaults and override testing to true | ||
Jarvis.options = Jarvis.option_defaults | ||
Jarvis.options[:logfile] = '/dev/null' | ||
Jarvis.options[:testing] = true | ||
Jarvis.log = Jarvis.default_logger | ||
|
||
# Reset the commands array. This stops duplicate command errors. | ||
Jarvis::Command.reset | ||
|
||
@jarvis = Jarvis::MusicServer.new nil | ||
@last_response = nil | ||
end | ||
|
||
after :each do | ||
@jarvis.unbind | ||
@jarvis = nil | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
require 'ogginfo' | ||
require 'fileutils' | ||
|
||
shared_context "timidity" do | ||
# Starts up timidity in an external process. It is told to output all sounds | ||
# in ogg vorbis format to a test.ogg file defined by the test_ogg_path method | ||
# of this context. | ||
def start_timidity | ||
@@timidity_pid = fork do | ||
exec "timidity -iA -Ov -o #{test_ogg_path}" | ||
end | ||
|
||
sleep(1) | ||
end | ||
|
||
# Stops the external timidity process. | ||
def stop_timidity | ||
if @@timidity_pid | ||
Process.kill('SIGINT', @@timidity_pid) | ||
Process.wait(@@timidity_pid) | ||
@@timidity_pid = nil | ||
end | ||
end | ||
|
||
# The absolute path to the test.ogg file that we are telling timidity to write | ||
# to. | ||
def test_ogg_path | ||
Jarvis::ROOTDIR + '/spec/data/test.ogg' | ||
end | ||
|
||
# Gets the designated test.ogg file from inside spec/data. If the ogg file is | ||
# empty or not there, nil will be returned. This is useful for asserting that | ||
# notes actually made it to the server. | ||
def test_ogg | ||
begin | ||
OggInfo.open(test_ogg_path) | ||
rescue Exception => e | ||
nil | ||
end | ||
end | ||
|
||
# Sets up an rspec hook to start the timidity server before each spec | ||
before :each do | ||
start_timidity | ||
end | ||
|
||
# Sets up an rspec hook to stop the timidity process after each spec | ||
after :each do | ||
stop_timidity | ||
|
||
FileUtils.rm test_ogg_path | ||
end | ||
end |