I’m eager to do all sorts of process improvement (including ditching Octopress), but decided that I
really wanted to get a bunch of tests done first. Spoiler: I actually only get one working today.
Scenario: Disallow connection if server in Starting mode
Given the server executable is started
When I do not allow time for the server to complete startup
Then I can not connect to the server via telnet
But it does mean splitting out some code. We need to be able to start the server and not wait for
it to come up. So we’ll just start the server and make sure the “Starting main game loop.”
message is not yet in the log. Then we’ll attempt a telnet connection and make sure it fails.
Given(/^the server executable is started$/)doexpect(start_server()).tobe_truthyendAnd(/^I do not allow time for the server to complete startup$/)doexpect(log_contains_immediate('Starting main game loop.')).tobe_falsyend
defstart_server()# Start up the server - we don't wait for it to come up in this methodresult=falseDir.chdir("test_env/test02")doresult=Process.spawn("DragSpinExp.exe",[:out,:err]=>["DragSpinExp.log","w"],:close_others=>true)puts"Result of start: #{result}"endresultend
deflog_contains_immediate(message)connect_hash={username:ENV['DB_USERNAME'],password:ENV['DB_PASSWORD'],dataserver:ENV['DB_DATASERVER'],database:ENV['DB_NAME']}puts"Connecting to #{ENV['DB_DATASERVER']} database #{ENV['DB_NAME']}..."client=TinyTds::Client.new(connect_hash)puts" Connected."ifclient.active?puts"Checking log for \"#{message}\"."result=client.execute("SELECT * FROM [#{ENV['DB_NAME']}].[dbo].[Log] WHERE message LIKE '#{message}'")rows_affected=result.dorows_affected>0end
defcreate_telnet_connection()rand_id=rand(36**20).to_s(36)puts"Creating telnet connection with ID #{rand_id}"beginconnection=Net::Telnet::new("Host"=>ENV['DS_HOST'],"Port"=>3000,"Output_log"=>"output_#{rand_id}.log","Dump_log"=>"dump_#{rand_id}.log","Prompt"=>"Login:","Telnetmode"=>false,"Timeout"=>20,"Waittime"=>1)rescueErrno::ECONNREFUSED=>eputse.inspectconnection=nilendconnectionend
And we begin to see how our test library will be expanded and refactored with each new test. The
only problem is that this test fails every time. The new minimal database is loaded so quickly that
we can never catch it early enough for the telnet to fail.
Scenario: Disallow connection if server in Starting mode
Given the production database is in use
When the server executable is started
And I do not allow time for the server to complete startup
Then I can not connect to the server via telnet
Given(/^the production database is in use$/)do# Kill the server if it's already runningresult=%x[taskkill /F /T /IM DragSpinExp.exe"]puts"Result of taskkill: #{result}"# Reset the databaseresult=%x[sqlcmd -S "#{ENV['DB_DATASERVER']}" -U "#{ENV['DB_USERNAME']}" -P "#{ENV['DB_PASSWORD']}" -i EntireDB-production.sql -o EntireDB-production.out]puts"Result of sqlcmd: #{result}"end
With the full production database, there’s plenty of time to catch the server in a “not ready yet”
state:
Hooray for passed test, but over six minutes to run? Most of that is populating the production
database. We’ll have to find a faster way to handle that.
Let’s store multiple databases (minimal and production for now), and only fully rebuild them
when we need to. After a fair amount of reworking the test code, we have an instance variable
@server_database that we use instead of the DB_NAME environment variable. We’ll use Nokogiri
to modify the server config XML to point to the correct database:
For tests like this one, where we just want one database or the other and don’t care what state
it’s in, we have a step and method to select a database and only build it if it doesn’t exist:
Given(/^I use the production database as-is$/)do# Kill the server if it's already runningresult=%x[taskkill /F /T /IM DragSpinExp.exe"]puts"Result of taskkill: #{result}"@server_database="production"load_db_if_absent(@server_database)set_db_in_config(@server_database)end