tyrantmanager 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'logging'
4
+
5
+ $:.unshift File.expand_path( File.join( File.dirname( __FILE__ ),"..","lib"))
6
+
7
+
8
+ Logging::Logger['TyrantManager'].level = :all
9
+
10
+ module Spec
11
+ module Log
12
+ def self.io
13
+ @io ||= StringIO.new
14
+ end
15
+ def self.appender
16
+ @appender ||= Logging::Appenders::IO.new( "speclog", io )
17
+ end
18
+
19
+ Logging::Logger['TyrantManager'].add_appenders( Log.appender )
20
+
21
+ def self.layout
22
+ @layout ||= Logging::Layouts::Pattern.new(
23
+ :pattern => "[%d] %5l %6p %c : %m\n",
24
+ :date_pattern => "%Y-%m-%d %H:%M:%S"
25
+ )
26
+ end
27
+
28
+ Log.appender.layout = layout
29
+ end
30
+
31
+ module Helpers
32
+ require 'tmpdir'
33
+ def temp_dir( unique_id = $$ )
34
+ dirname = File.join( Dir.tmpdir, "tyrant-spec-#{unique_id}" )
35
+ FileUtils.mkdir_p( dirname ) unless File.directory?( dirname )
36
+ # for osx
37
+ dirname = Dir.chdir( dirname ) { Dir.pwd }
38
+ end
39
+
40
+ def spec_log
41
+ Log.io.string
42
+ end
43
+ end
44
+ end
45
+
46
+ Spec::Runner.configure do |config|
47
+ config.include Spec::Helpers
48
+
49
+ config.before do
50
+ Spec::Log.io.rewind
51
+ Spec::Log.io.truncate( 0 )
52
+ end
53
+
54
+ config.after do
55
+ Spec::Log.io.rewind
56
+ Spec::Log.io.truncate( 0 )
57
+ end
58
+ end
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
2
+
3
+ require 'tyrant_manager'
4
+ require 'tyrant_manager/tyrant_instance'
5
+
6
+ describe TyrantManager::TyrantInstance do
7
+ before( :each ) do
8
+ @tdir = File.join( temp_dir, 'tyrant' )
9
+ TyrantManager::Log.silent {
10
+ @mgr = TyrantManager.setup( @tdir )
11
+ @idir = @mgr.instances_path( "test" )
12
+ @tyrant = TyrantManager::TyrantInstance.setup( @idir )
13
+ @tyrant.manager = @mgr
14
+ }
15
+ end
16
+
17
+ after( :each ) do
18
+ FileUtils.rm_rf @tdir
19
+ end
20
+
21
+ it "raises an exception if given an invalid directory on initialization" do
22
+ lambda { TyrantManager::TyrantInstance.new( "/tmp" ) }.should raise_error( TyrantManager::Error, /tmp is not a valid archive/ )
23
+ end
24
+
25
+ it "#config_file" do
26
+ @tyrant.config_file.should == File.join( @tdir, "instances", "test", "config.rb" )
27
+ File.exist?( @tyrant.config_file ).should == true
28
+ end
29
+
30
+ it "#configuration" do
31
+ @tyrant.configuration.should_not == nil
32
+ end
33
+
34
+ it "#pid_file" do
35
+ @tyrant.pid_file.should == File.join( @tdir, "instances", "test", "test.pid" )
36
+ end
37
+
38
+ it "#log_file" do
39
+ @tyrant.log_file.should == File.join( @tdir, "instances", "test", "log", "test.log" )
40
+ end
41
+
42
+ it "#replication_timestamp_file" do
43
+ @tyrant.replication_timestamp_file.should == File.join( @tdir, "instances", "test", "test.rts" )
44
+ end
45
+
46
+ it "#lua_extension_file" do
47
+ @tyrant.lua_extension_file.should == File.join( @tdir, "instances", "test", "lua", "test.lua" )
48
+ end
49
+
50
+ it "#data_dir" do
51
+ @tyrant.data_dir.should == File.join( @tdir, "instances", "test", "data" )
52
+ end
53
+
54
+
55
+ describe "database types" do
56
+ { 'memory-hash' => "*",
57
+ 'memory-tree' => "+",
58
+ 'hash' => "tch",
59
+ 'tree' => "tcb",
60
+ 'fixed' => "tcf",
61
+ 'table' => "tct"
62
+ }.each_pair do |db_type, db_ext|
63
+ it "db_type of #{db_type} is db file with ext #{db_ext}" do
64
+ f = @tyrant.db_file( db_type )
65
+ if f.size == 1 then
66
+ f.should == db_ext
67
+ else
68
+ f.should == File.join( @tdir, "instances", "test", "data", "test.#{db_ext}" )
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ it "#ulog_dir" do
75
+ @tyrant.ulog_dir.should == File.join( @tdir, "instances", "test", "ulog" )
76
+ end
77
+
78
+
79
+ it "#start_command" do
80
+ @tyrant.start_command.should =~ /^ttserver/
81
+ end
82
+
83
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
2
+
3
+ require 'tyrant_manager'
4
+
5
+ describe TyrantManager do
6
+ before( :each ) do
7
+ @tdir = File.join( temp_dir, 'tyrant' )
8
+ TyrantManager::Log.silent {
9
+ @mgr = TyrantManager.setup( @tdir )
10
+ }
11
+ #TyrantManager::Log.level = :debug
12
+ end
13
+
14
+ after( :each ) do
15
+ #puts spec_log
16
+ FileUtils.rm_rf @tdir
17
+ end
18
+
19
+ describe "#default_directory" do
20
+ it "uses the current working directory" do
21
+ Dir.chdir( @tdir ) do |d|
22
+ TyrantManager.default_directory.should == d
23
+ end
24
+ end
25
+
26
+ it "uses the TYRANT_MANAGER_HOME environment variable" do
27
+ ENV['TYRANT_MANAGER_HOME'] = @tdir
28
+ TyrantManager.default_directory.should == @tdir
29
+ end
30
+ end
31
+
32
+ it "initializes with an existing directory" do
33
+ t = TyrantManager.new( @tdir )
34
+ t.config_file.should == File.join( @tdir, "config.rb" )
35
+ end
36
+
37
+ it "raises an error if attempting to initialize from a non-existent tyrnat home" do
38
+ lambda { TyrantManager.new( "/tmp" ) }.should raise_error( TyrantManager::Error, /\/tmp is not a valid archive/ )
39
+ end
40
+
41
+ it "#config_file" do
42
+ @mgr.config_file.should == File.join( @tdir, "config.rb" )
43
+ File.exist?( @mgr.config_file ).should == true
44
+ end
45
+
46
+ it "#configuration" do
47
+ @mgr.configuration.should_not == nil
48
+ end
49
+
50
+ it "has the location of the ttserver command" do
51
+ @mgr.configuration.ttserver.should == "ttserver"
52
+ end
53
+
54
+ it "knows all its instances" do
55
+ 3.times do |x|
56
+ idir = @mgr.instances_path( "test#{x}" )
57
+ TyrantManager::TyrantInstance.setup( idir )
58
+ end
59
+
60
+ @mgr.instances.size.should == 3
61
+ names = []
62
+ @mgr.each_instance do |i|
63
+ i.name.should =~ /test\d/
64
+ names << i.name
65
+ end
66
+
67
+ names.sort.should == %w[ test0 test1 test2 ]
68
+ end
69
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__),"spec_helper.rb"))
2
+
3
+ describe "TyrantManager::Version" do
4
+
5
+ it "should have a version string" do
6
+ TyrantManager::Version.to_s.should =~ /\d+\.\d+\.\d+/
7
+ TyrantManager::VERSION.should =~ /\d+\.\d+\.\d+/
8
+ end
9
+
10
+ it "should have a version hash" do
11
+ h = TyrantManager::Version.to_hash
12
+ [ :major, :minor, :build ].each do |k|
13
+ h[k].should_not be_nil
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,43 @@
1
+ require 'tasks/config'
2
+ #-------------------------------------------------------------------------------
3
+ # announcement methods
4
+ #-------------------------------------------------------------------------------
5
+
6
+ proj_config = Configuration.for('project')
7
+ namespace :announce do
8
+ desc "create email for ruby-talk"
9
+ task :email do
10
+ info = Utils.announcement
11
+
12
+ File.open("email.txt", "w") do |mail|
13
+ mail.puts "From: #{proj_config.author} <#{proj_config.email}>"
14
+ mail.puts "To: ruby-talk@ruby-lang.org"
15
+ mail.puts "Date: #{Time.now.rfc2822}"
16
+ mail.puts "Subject: [ANN] #{info[:subject]}"
17
+ mail.puts
18
+ mail.puts info[:title]
19
+ mail.puts
20
+ mail.puts "{{ Release notes for Version #{TyrantManager::VERSION} }}"
21
+ mail.puts
22
+ mail.puts info[:release_notes]
23
+ mail.puts
24
+ mail.puts " #{info[:urls]}"
25
+ mail.puts
26
+ mail.puts "=== Installation"
27
+ mail.puts
28
+ mail.puts " gem install #{TyrantManager::GEM_SPEC.name}"
29
+ mail.puts
30
+ mail.puts "=== Description"
31
+ mail.puts
32
+ mail.puts info[:description]
33
+ mail.puts
34
+ end
35
+ puts "Created the following as email.txt:"
36
+ puts "-" * 72
37
+ puts File.read("email.txt")
38
+ puts "-" * 72
39
+ end
40
+
41
+ CLOBBER << "email.txt"
42
+ end
43
+
data/tasks/config.rb ADDED
@@ -0,0 +1,99 @@
1
+ require 'configuration'
2
+
3
+ require 'rake'
4
+ require 'tasks/utils'
5
+
6
+ #-----------------------------------------------------------------------
7
+ # General project configuration
8
+ #-----------------------------------------------------------------------
9
+ Configuration.for('project') {
10
+ name "tyrantmanager"
11
+ version TyrantManager::VERSION
12
+ author "Jeremy Hinegardner"
13
+ email "jeremy@copiousfreetime.org"
14
+ homepage "http://copiousfreetime.rubyforge.org/tyrantmanager/"
15
+ description Utils.section_of("README", "description")
16
+ summary description.split(".").first
17
+ history "HISTORY"
18
+ license FileList["LICENSE"]
19
+ readme "README"
20
+ }
21
+
22
+ #-----------------------------------------------------------------------
23
+ # Packaging
24
+ #-----------------------------------------------------------------------
25
+ Configuration.for('packaging') {
26
+ # files in the project
27
+ proj_conf = Configuration.for('project')
28
+ files {
29
+ bin FileList["bin/*"]
30
+ ext FileList["ext/*.{c,h,rb}"]
31
+ lib FileList["lib/**/*.rb"]
32
+ test FileList["spec/**/*.rb", "test/**/*.rb"]
33
+ data FileList["data/**/*"]
34
+ tasks FileList["tasks/**/*.r{ake,b}"]
35
+ rdoc FileList[proj_conf.readme, proj_conf.history,
36
+ proj_conf.license] + lib
37
+ all bin + ext + lib + test + data + rdoc + tasks
38
+ }
39
+
40
+ # ways to package the results
41
+ formats {
42
+ tgz true
43
+ zip true
44
+ rubygem Configuration::Table.has_key?('rubygem')
45
+ }
46
+ }
47
+
48
+ #-----------------------------------------------------------------------
49
+ # Gem packaging
50
+ #-----------------------------------------------------------------------
51
+ Configuration.for("rubygem") {
52
+ spec "gemspec.rb"
53
+ Configuration.for('packaging').files.all << spec
54
+ }
55
+
56
+ #-----------------------------------------------------------------------
57
+ # Testing
58
+ # - change mode to 'testunit' to use unit testing
59
+ #-----------------------------------------------------------------------
60
+ Configuration.for('test') {
61
+ mode "spec"
62
+ files Configuration.for("packaging").files.test
63
+ options %w[ --format specdoc --color ]
64
+ ruby_opts %w[ ]
65
+ }
66
+
67
+ #-----------------------------------------------------------------------
68
+ # Rcov
69
+ #-----------------------------------------------------------------------
70
+ Configuration.for('rcov') {
71
+ output_dir "coverage"
72
+ libs %w[ lib ]
73
+ rcov_opts %w[ --html ]
74
+ ruby_opts %w[ ]
75
+ test_files Configuration.for('packaging').files.test
76
+ }
77
+
78
+ #-----------------------------------------------------------------------
79
+ # Rdoc
80
+ #-----------------------------------------------------------------------
81
+ Configuration.for('rdoc') {
82
+ files Configuration.for('packaging').files.rdoc
83
+ main_page files.first
84
+ title Configuration.for('project').name
85
+ options %w[ ]
86
+ output_dir "doc"
87
+ }
88
+
89
+ #-----------------------------------------------------------------------
90
+ # Rubyforge
91
+ #-----------------------------------------------------------------------
92
+ Configuration.for('rubyforge') {
93
+ project "copiousfreetime"
94
+ user "jjh"
95
+ host "rubyforge.org"
96
+ rdoc_location "#{user}@#{host}:/var/www/gforge-projects/#{project}/tyrantmanager/"
97
+ }
98
+
99
+
@@ -0,0 +1,38 @@
1
+ require 'tasks/config'
2
+
3
+ #-------------------------------------------------------------------------------
4
+ # Distribution and Packaging
5
+ #-------------------------------------------------------------------------------
6
+ if pkg_config = Configuration.for_if_exist?("packaging") then
7
+
8
+ require 'gemspec'
9
+ require 'rake/gempackagetask'
10
+ require 'rake/contrib/sshpublisher'
11
+
12
+ namespace :dist do
13
+
14
+ Rake::GemPackageTask.new(TyrantManager::GEM_SPEC) do |pkg|
15
+ pkg.need_tar = pkg_config.formats.tgz
16
+ pkg.need_zip = pkg_config.formats.zip
17
+ end
18
+
19
+ desc "Install as a gem"
20
+ task :install => [:clobber, :package] do
21
+ sh "sudo gem install pkg/#{TyrantManager::GEM_SPEC.full_name}.gem"
22
+ end
23
+
24
+ desc "Uninstall gem"
25
+ task :uninstall do
26
+ sh "sudo gem uninstall -x #{TyrantManager::GEM_SPEC.name}"
27
+ end
28
+
29
+ desc "dump gemspec"
30
+ task :gemspec do
31
+ puts TyrantManager::GEM_SPEC.to_ruby
32
+ end
33
+
34
+ desc "reinstall gem"
35
+ task :reinstall => [:uninstall, :repackage, :install]
36
+
37
+ end
38
+ end
@@ -0,0 +1,32 @@
1
+ require 'tasks/config'
2
+
3
+ #-----------------------------------------------------------------------
4
+ # Documentation
5
+ #-----------------------------------------------------------------------
6
+
7
+ if rdoc_config = Configuration.for_if_exist?('rdoc') then
8
+
9
+ namespace :doc do
10
+
11
+ require 'rdoc'
12
+ require 'rake/rdoctask'
13
+
14
+ # generating documentation locally
15
+ Rake::RDocTask.new do |rdoc|
16
+ rdoc.rdoc_dir = rdoc_config.output_dir
17
+ rdoc.options = rdoc_config.options
18
+ rdoc.rdoc_files = rdoc_config.files
19
+ rdoc.title = rdoc_config.title
20
+ rdoc.main = rdoc_config.main_page
21
+ end
22
+
23
+ if rubyforge_config = Configuration.for_if_exist?('rubyforge') then
24
+ desc "Deploy the RDoc documentation to #{rubyforge_config.rdoc_location}"
25
+ task :deploy => :rerdoc do
26
+ sh "rsync -zav --delete #{rdoc_config.output_dir}/ #{rubyforge_config.rdoc_location}"
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+
data/tasks/rspec.rake ADDED
@@ -0,0 +1,29 @@
1
+
2
+ require 'tasks/config'
3
+
4
+ #--------------------------------------------------------------------------------
5
+ # configuration for running rspec. This shows up as the test:default task
6
+ #--------------------------------------------------------------------------------
7
+ if spec_config = Configuration.for_if_exist?("test") then
8
+ if spec_config.mode == "spec" then
9
+ namespace :test do
10
+
11
+ task :default => :spec
12
+
13
+ require 'spec/rake/spectask'
14
+ Spec::Rake::SpecTask.new do |r|
15
+ r.ruby_opts = spec_config.ruby_opts
16
+ r.libs = [ TyrantManager.lib_path,
17
+ TyrantManager.install_dir ]
18
+ r.spec_files = spec_config.files
19
+ r.spec_opts = spec_config.options
20
+
21
+ if rcov_config = Configuration.for_if_exist?('rcov') then
22
+ r.rcov = true
23
+ r.rcov_dir = rcov_config.output_dir
24
+ r.rcov_opts = rcov_config.rcov_opts
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,51 @@
1
+ require 'tasks/config'
2
+
3
+ #-----------------------------------------------------------------------
4
+ # Rubyforge additions to the task library
5
+ #-----------------------------------------------------------------------
6
+ if rf_conf = Configuration.for_if_exist?("rubyforge") then
7
+
8
+ abort("rubyforge gem not installed 'gem install rubyforge'") unless Utils.try_require('rubyforge')
9
+
10
+ proj_conf = Configuration.for('project')
11
+
12
+ namespace :dist do
13
+ desc "Release files to rubyforge"
14
+ task :rubyforge => [:clean, :package] do
15
+
16
+ rubyforge = RubyForge.new
17
+
18
+ config = {}
19
+ config["release_notes"] = proj_conf.description
20
+ config["release_changes"] = Utils.release_notes_from(proj_conf.history)[TyrantManager::VERSION]
21
+ config["Prefomatted"] = true
22
+
23
+ rubyforge.configure
24
+
25
+ # make sure this release doesn't already exist
26
+ releases = rubyforge.autoconfig['release_ids']
27
+ if releases.has_key?(TyrantManager::GEM_SPEC.name) and releases[TyrantManager::GEM_SPEC.name][TyrantManager::VERSION] then
28
+ abort("Release #{TyrantManager::VERSION} already exists! Unable to release.")
29
+ end
30
+
31
+ puts "Uploading to rubyforge..."
32
+ files = FileList[File.join("pkg","#{TyrantManager::GEM_SPEC.name}-#{TyrantManager::VERSION}*.*")].to_a
33
+ rubyforge.login
34
+ rubyforge.add_release(TyrantManager::GEM_SPEC.rubyforge_project, TyrantManager::GEM_SPEC.name, TyrantManager::VERSION, *files)
35
+ puts "done."
36
+ end
37
+ end
38
+
39
+ namespace :announce do
40
+ desc "Post news of #{proj_conf.name} to #{rf_conf.project} on rubyforge"
41
+ task :rubyforge do
42
+ info = Utils.announcement
43
+ rubyforge = RubyForge.new
44
+ rubyforge.configure
45
+ rubyforge.login
46
+ rubyforge.post_news(rf_conf.project, info[:subject], "#{info[:title]}\n\n#{info[:urls]}\n\n#{info[:release_notes]}")
47
+ puts "Posted to rubyforge"
48
+ end
49
+
50
+ end
51
+ end
data/tasks/utils.rb ADDED
@@ -0,0 +1,80 @@
1
+ require 'tyrant_manager/version'
2
+
3
+ #-------------------------------------------------------------------------------
4
+ # Additions to the Configuration class that are useful
5
+ #-------------------------------------------------------------------------------
6
+ class Configuration
7
+ class << self
8
+ def exist?( name )
9
+ Configuration::Table.has_key?( name )
10
+ end
11
+
12
+ def for_if_exist?( name )
13
+ if self.exist?( name ) then
14
+ self.for( name )
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ #-------------------------------------------------------------------------------
21
+ # some useful utilitiy methods for the tasks
22
+ #-------------------------------------------------------------------------------
23
+ module Utils
24
+ class << self
25
+
26
+ # Try to load the given _library_ using the built-in require, but do not
27
+ # raise a LoadError if unsuccessful. Returns +true+ if the _library_ was
28
+ # successfully loaded; returns +false+ otherwise.
29
+ #
30
+ def try_require( lib )
31
+ require lib
32
+ true
33
+ rescue LoadError
34
+ false
35
+ end
36
+
37
+ # partition an rdoc file into sections, and return the text of the section
38
+ # given.
39
+ def section_of(file, section_name)
40
+ File.read(file).split(/^(?==)/).each do |section|
41
+ lines = section.split("\n")
42
+ return lines[1..-1].join("\n").strip if lines.first =~ /#{section_name}/i
43
+ end
44
+ nil
45
+ end
46
+
47
+ # Get an array of all the changes in the application for a particular
48
+ # release. This is done by looking in the history file and grabbing the
49
+ # information for the most recent release. The history file is assumed to
50
+ # be in RDoc format and version release are 2nd tier sections separated by
51
+ # '== Version X.Y.Z'
52
+ #
53
+ # returns:: A hash of notes keyed by version number
54
+ #
55
+ def release_notes_from(history_file)
56
+ releases = {}
57
+ File.read(history_file).split(/^(?==)/).each do |section|
58
+ lines = section.split("\n")
59
+ md = %r{Version ((\w+\.)+\w+)}.match(lines.first)
60
+ next unless md
61
+ releases[md[1]] = lines[1..-1].join("\n").strip
62
+ end
63
+ return releases
64
+ end
65
+
66
+ # return a hash of useful information for the latest release
67
+ # urls, subject, title, description and latest release notes
68
+ #
69
+ def announcement
70
+ cfg = Configuration.for("project")
71
+ {
72
+ :subject => "#{cfg.name} #{TyrantManager::VERSION} Released",
73
+ :title => "#{cfg.name} version #{TyrantManager::VERSION} has been released.",
74
+ :urls => "#{cfg.homepage}",
75
+ :description => "#{cfg.description.rstrip}",
76
+ :release_notes => Utils.release_notes_from(cfg.history)[TyrantManager::VERSION].rstrip
77
+ }
78
+ end
79
+ end
80
+ end # << self