diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b10138c39575da2ca1ae9f16cbe95f1f56e4c3e2..0e81abf597779dfee2cd495ab6c4f602a003771d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,7 @@
 image: ruby:2.3
 
 before_script:
-  - apt-get update -qq && apt-get install -y -qq libbluetooth-dev cmake
+  - apt-get update -qq && apt-get install -y -qq libbluetooth-dev cmake valgrind
 
 stages:
   - build
diff --git a/quad/Makefile b/quad/Makefile
index b6838e4bfdc801ae4c8401f8c06eb5941e706557..b3d2929b7d5a0865ca98d033eddbb562381169c0 100644
--- a/quad/Makefile
+++ b/quad/Makefile
@@ -39,8 +39,8 @@ test: all
 	$(MAKE) -C src/computation_graph test
 	$(MAKE) -C src/quad_app test
 	ruby scripts/tests/test_safety_checks.rb
+	ruby scripts/tests/test_memory_integrity.rb
 	# ruby scripts/tests/test_unix_uart.rb
-	# ruby scripts/tests/run_virtual_test_flight.rb
 
 clean:
 	rm -rf $(INCDIR) $(LIBDIR) $(OUTDIR) $(EXEDIR)
diff --git a/quad/scripts/tests/test_memory_integrity.rb b/quad/scripts/tests/test_memory_integrity.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f422b49e81043f469d93b5f3f5eb87d0f62252ef
--- /dev/null
+++ b/quad/scripts/tests/test_memory_integrity.rb
@@ -0,0 +1,105 @@
+#!/usr/bin/env ruby
+
+# Test Flight
+#
+# A simple virtual test flight (take off, hover, and set back down)
+# with valgrind, in order to detect memory leaks
+
+script_dir = File.expand_path(File.dirname(__FILE__))
+require script_dir + "/testing_library"
+
+bin_dir = script_dir + "/../../bin/"
+Dir.chdir(bin_dir)
+
+puts("Firing up the quad...")
+
+# Start virtual quad
+quad = Process.spawn("valgrind --leak-check=full --log-file=./valgrind.out ./virt-quad")
+
+delay_spin_cursor(3)
+
+set_gear GEAR_OFF
+set_flap FLAP_ON
+
+##################
+#  Begin Flight!
+##################
+
+begin
+  puts("Starting flight...")
+
+  # Set initial quad orientation (flat on ground, facing forward)
+  `./virt-quad set i2c_imu_x 0`
+  `./virt-quad set i2c_imu_y 0`
+  `./virt-quad set i2c_imu_z -1`
+  `./virt-quad set rc_roll 0.498`
+  `./virt-quad set rc_pitch 0.497`
+  `./virt-quad set rc_yaw 0.498`
+
+  puts("Turning on GEAR...")
+  set_gear GEAR_ON
+  sleep 0.015
+
+  puts("Increasing Thrust to half maximum...")
+  for i in (THROTTLE_MIN..THROTTLE_MID).step(0.01)
+    set_throttle(i)
+    sleep 0.005
+  end
+
+  puts("Hovering for 5 seconds")
+  delay_spin_cursor(5)
+
+  puts("Switching to autonomous and hovering for 5 seconds")
+  set_flap FLAP_ON
+  delay_spin_cursor(5)
+
+  puts("Switch back to manual, relaxing thrust to zero")
+  set_flap FLAP_OFF
+  i = THROTTLE_MID
+  while i > THROTTLE_MIN
+    i -= 0.01
+    set_throttle(i)
+    sleep 0.005
+  end
+
+  puts("Swiching off GEAR...")
+  set_gear GEAR_OFF
+
+  # puts("Collecting logs...")
+  # msg = ""
+  # misses = 0
+  # fifo = File::open(UART_TX)
+  # while misses < 10
+  #   puts "trying..."
+  #   if fifo.eof?
+  #     misses += 1
+  #     next
+  #   end
+  #   msg += fifo.read()
+  # end
+  
+  # fifo.close()
+
+# puts msg
+
+  puts("Flight ended successfully.");
+ensure
+
+  Process.kill(2, quad)
+
+  sleep 1 # wait for valgrind to write to file
+
+  # Process the valgrind file
+  file = File.open("./valgrind.out")
+  everything = file.readlines
+  last_line = everything.last
+  errors = last_line.scanf("%s ERROR SUMMARY: %d errors %s")
+  if errors[1] > 0
+    puts everything
+    puts "Memory Integrity Check Failed."
+    Kernel.exit(1)
+  end
+
+  puts "Memory Integrity Check Passed."
+end
+
diff --git a/quad/scripts/tests/test_safety_checks.rb b/quad/scripts/tests/test_safety_checks.rb
index 20c49fb33a75780419aa360794e8d3a757473766..f7cd8ddb0e4ba010ce4e5b0feb717678a6c3e35f 100644
--- a/quad/scripts/tests/test_safety_checks.rb
+++ b/quad/scripts/tests/test_safety_checks.rb
@@ -83,7 +83,7 @@ Timeout::timeout(60) {
 
     puts("Check that motors turn on")
     set_throttle THROTTLE_MID
-    spinner = Thread.new { delay_spin_cursor(5) }
+    spinner = Thread.new { delay_spin_cursor(3) }
     motors = get_motor_averages(100, 3)
     spinner.exit
     p motors
@@ -92,7 +92,7 @@ Timeout::timeout(60) {
     puts("Check that when quad is tilted, motors respond correctly")
     puts("Tilting forwards...")
     `./virt-quad set i2c_imu_x 0.25`
-    spinner = Thread.new { delay_spin_cursor(5) }
+    spinner = Thread.new { delay_spin_cursor(3) }
     motors = get_motor_averages(100, 3)
     spinner.exit
     p motors
@@ -102,7 +102,7 @@ Timeout::timeout(60) {
     assert_operator(motors[2], :>, motors[3])
     puts("Tilting backwards...")
     `./virt-quad set i2c_imu_x -0.25`
-    spinner = Thread.new { delay_spin_cursor(5) }
+    spinner = Thread.new { delay_spin_cursor(3) }
     motors = get_motor_averages(100, 3)
     spinner.exit
     p motors
@@ -113,7 +113,7 @@ Timeout::timeout(60) {
     puts("Tilting right...")
     `./virt-quad set i2c_imu_x 0`
     `./virt-quad set i2c_imu_y 0.25`
-    spinner = Thread.new { delay_spin_cursor(5) }
+    spinner = Thread.new { delay_spin_cursor(3) }
     motors = get_motor_averages(100, 3)
     spinner.exit
     p motors
@@ -123,7 +123,7 @@ Timeout::timeout(60) {
     assert_operator(motors[1], :<, motors[3])
     puts("Tilting left...")
     `./virt-quad set i2c_imu_y -0.25`
-    spinner = Thread.new { delay_spin_cursor(5) }
+    spinner = Thread.new { delay_spin_cursor(3) }
     motors = get_motor_averages(100, 3)
     spinner.exit
     p motors
diff --git a/quad/scripts/tests/testing_library.rb b/quad/scripts/tests/testing_library.rb
index 6301d840d821f51356b1df742f7a1490fff98fb5..e8afdc7a01574016cc861c265624c422b2fbd9ef 100644
--- a/quad/scripts/tests/testing_library.rb
+++ b/quad/scripts/tests/testing_library.rb
@@ -33,6 +33,7 @@ UART_TX = "virt-quad-fifos/uart-tx"
 require 'test/unit/assertions'
 require 'timeout'
 require 'thread'
+require 'scanf'
 include Test::Unit::Assertions
 
 # Utility functions