Using isTest() to prevent accidentally updating live data

This post was originally written for Iguana 5 so it contains version 5 screenshots, and may contain out of date references.

We don’t want to update live data in in “test mode”, when we are editing a script. Annotations, auto-complete and the preview pane for resubmitting messages, all generate data by running editor scripts and can potentially update live data if you do not take precautions.

As a safeguard our net.* libraries and our db.* libraries by default do not execute any “external operations” in test mode (this greatly reduces the risk of accidental updates). So if you wanted to update a test database, or run a test net.* command you first need to set the appropriate live parameter to true. However iguana.isTest() becomes useful when your code changes external resources or data, for example: using io.* functions to update files, os.* to move/delete files, or os.execute() to run external scripts/applications.

To prevent data from being updated in “test mode” we simply use the iguana.isTest() function:

if not iguana.isTest() then
   -- do stuff that I only want to run when the channel is live
   -- NOTE: this code will not run in the editor (test mode)
end

We can also use it to prevent testing code being run in a live channel:

if iguana.isTest() then
   -- run testing code 
   -- NOTE: this code will not be run in the live channel
end

You can also choose different behaviours for live and test mode:

if iguana.isTest() then
   -- do stuff that I do not want to run live
   -- update the Test database, write data to a Test file or display with trace()
else
   -- do stuff I want to run live
   -- update the Live database, or write data to a Live file etc.
end

Examples

Using a database:

We used SQLite and queried the sqlite_master system table (because it always exists).

Here is code so you can try it. The code should just work (the SQLite databases will be created automatically if they do not exist).

local conn_test = db.connect{
   api=db.SQLITE,
   name='test', 
   live=true
}

local conn_live = db.connect{
   api=db.SQLITE,
   name='live', 
   live=true -- bad practice should set to false
}

function main(Data)

   local R_test, R_live

   -- only the test query will run
   if iguana.isTest() then
      R_test = conn_test:query("SELECT * FROM sqlite_master")
   else
      R_live = conn_live:query("SELECT * FROM sqlite_master")      
   end
   trace(R_test, R_live) -- live returns nil = no query run

   -- run live query
   R_live = conn_live:query("SELECT * FROM sqlite_master")      
   trace(R_test, R_live) -- live returns a result set

end

Updating files:

We show an example of renaming a file, we create a file “test.txt” in the Iguana directory and rename it. In a production situation you could use something similar to process and rename files that are delivered periodically.

Every time you run the code you will create a renamed file (in the Iguana install directory):

Here is code so you can try it.

function main(Data)

   -- create test file (if it does not exist)
   -- in production the file would be delivered periodically
   local f = io.open('test.txt', 'w')
   f:write('Hello World!')
   f:close()

   -- only change the file name in the live channel
   if iguana.isTest() then
      f = io.open('test.txt', 'r')
      f:read('*a')
      f:close()
   else
      os.rename('test.txt','test_'..tostring(os.time())..'.txt')
   end  
end

Leave A Comment?

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.