Running VNC server for the headless display #26

Closed
wants to merge 4 commits into
from
Jump to file or symbol
Failed to load files and symbols.
+119 −2
Diff settings

Always

Just for now

View
@@ -1,5 +1,6 @@
require 'headless/cli_util'
require 'headless/video/video_recorder'
+require 'headless/vnc/vnc'
# A class incapsulating the creation and usage of a headless X server
#
@@ -112,6 +113,10 @@ def video
@video_recorder ||= VideoRecorder.new(display, dimensions, @video_capture_options)
end
+ def vnc
+ @vnc ||= Vnc.new(display)
+ end
+
def take_screenshot(file_path)
CliUtil.ensure_application_exists!('import', "imagemagick not found on your system. Please install it using sudo apt-get install imagemagick")
View
@@ -0,0 +1,39 @@
+require 'tempfile'
+
+class Headless
+ class Vnc
+ attr_accessor :pid_file_path, :log_file_path
+
+ def vnc_running?
+ !!read_vnc_pid
+ end
+
+ def read_vnc_pid
+ CliUtil.read_pid(@pid_file_path)
+ end
+
+ def initialize(display, options = {})
+ CliUtil.ensure_application_exists!('x11vnc', 'x11vnc not found on your system. Install it with sudo apt-get install x11vnc')
+
+ @display = display
+
+ @pid_file_path = options.fetch(:pid_file_path, "/tmp/.headless_vnc_#{@display}.pid")
+ @log_file_path = options.fetch(:log_file_path, "/dev/null")
+ end
+
+ def start
+ unless vnc_running?
+ CliUtil.fork_process("#{CliUtil.path_to('x11vnc')} -display :#{@display} -N -nopw -viewonly -shared -forever", @pid_file_path, @log_file_path)
+ at_exit do
+ exit_status = $!.status if $!.is_a?(SystemExit)
+ stop
+ exit exit_status if exit_status
+ end
+ end
+ end
+
+ def stop
+ CliUtil.kill_process(@pid_file_path, :wait => true)
+ end
+ end
+end
View
@@ -1,4 +1,4 @@
-require 'lib/headless'
+require 'spec_helper'
describe Headless do
before do
@@ -97,6 +97,19 @@
end
end
+ context "#vnc" do
+ let(:headless) { Headless.new }
+
+ it "returns a vnc" do
+ headless.vnc.should be_a_kind_of(Headless::Vnc)
+ end
+
+ it "returns the same instance" do
+ vnc = headless.vnc
+ headless.vnc.should be_eql(vnc)
+ end
+ end
+
context "#take_screenshot" do
let(:headless) { Headless.new }
View
@@ -0,0 +1,3 @@
+$LOAD_PATH << File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__))
+
+require 'headless'
@@ -1,4 +1,4 @@
-require 'lib/headless'
+require 'spec_helper'
describe Headless::VideoRecorder do
before do
View
@@ -0,0 +1,57 @@
+require 'spec_helper'
+
+describe Headless::Vnc do
+ before do
+ stub_environment
+ end
+
+ describe "instaniation" do
+ before do
+ Headless::CliUtil.stub!(:application_exists?).and_return(false)
+ end
+
+ it "throws an error if x11vnc is not installed" do
+ lambda { Headless::Vnc.new(99, 5900) }.should raise_error(Headless::Exception)
+ end
+ end
+
+ describe "start" do
+ it "starts x11vnc" do
+ Headless::CliUtil.stub(:path_to, 'x11vnc').and_return('x11vnc')
+ Headless::CliUtil.should_receive(:fork_process).with(/x11vnc -display :99 -N -nopw -viewonly -shared -forever/, "/tmp/.headless_vnc_99.pid", '/dev/null')
+
+ recorder = Headless::Vnc.new(99)
+ recorder.start
+ end
+
+ it "should not start x11vnc if it's already running" do
+ Headless::CliUtil.stub(:path_to, 'x11vnc').and_return('x11vnc')
+ Headless::CliUtil.stub(:read_pid).and_return('123')
+ Headless::CliUtil.should_not_receive(:fork_process)
+
+ recorder = Headless::Vnc.new(99)
+ recorder.start
+ end
+ end
+
+ context "stop" do
+ subject do
+ recorder = Headless::Vnc.new(99, :pid_file_path => "/tmp/pid")
+ recorder.start
+ recorder
+ end
+
+ it "stops kills the server" do
+ Headless::CliUtil.should_receive(:kill_process).with("/tmp/pid", :wait => true)
+
+ subject.stop()
+ end
+ end
+
+ private
+
+ def stub_environment
+ Headless::CliUtil.stub!(:application_exists?).and_return(true)
+ Headless::CliUtil.stub!(:fork_process).and_return(true)
+ end
+end