jeka 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/Gemfile.lock +55 -2
- data/README.rdoc +6 -14
- data/VERSION +1 -1
- data/bin/jeka +64 -94
- data/jeka.gemspec +56 -28
- data/lib/jeka.rb +6 -4
- data/lib/jeka/algorithm.rb +106 -24
- data/lib/jeka/analysis.rb +15 -0
- data/lib/jeka/analysis/algorithm.rb +13 -0
- data/lib/jeka/analysis/compiler.rb +14 -0
- data/lib/jeka/analysis/compiler_option.rb +24 -0
- data/lib/jeka/analysis/database.rb +11 -0
- data/lib/jeka/analysis/implementation.rb +15 -0
- data/lib/jeka/analysis/implementation_information.rb +24 -0
- data/lib/jeka/analysis/result.rb +20 -0
- data/lib/jeka/analysis/source_file.rb +24 -0
- data/lib/jeka/analysis/test.rb +15 -0
- data/lib/jeka/analysis/test_case.rb +13 -0
- data/lib/jeka/compilers.rb +3 -0
- data/lib/jeka/compilers/compiler.rb +48 -0
- data/lib/jeka/compilers/gpp.rb +29 -0
- data/lib/jeka/compilers/ruby.rb +21 -0
- data/lib/jeka/console.rb +55 -0
- data/lib/jeka/implementation.rb +22 -97
- data/lib/jeka/test.rb +15 -31
- data/lib/jeka/test_case.rb +41 -0
- data/test/bubble_sort/_tests/_test_01.rb +13 -0
- data/test/bubble_sort/algorithm_bubble_sort.rb +15 -0
- data/test/bubble_sort/cpp/_implementation.yaml +3 -0
- data/test/{example/01_bubble_sort/cpp/bubble.cpp → bubble_sort/cpp/bubble_sort.cpp} +9 -10
- data/test/bubble_sort/ruby/_implementation.yaml +3 -0
- data/test/{example/01_bubble_sort/ruby/bubble.rb → bubble_sort/ruby/bubble_sort.rb} +2 -5
- data/test/double/_tests/_test_01.rb +13 -0
- data/test/double/algorithm_double.rb +15 -0
- data/test/double/cpp/double.cpp +10 -0
- data/test/double/ruby/double.rb +2 -0
- data/test/test_algorithm.rb +25 -11
- data/test/test_gpp.rb +29 -0
- data/test/test_implementation.rb +25 -10
- data/test/test_test_case.rb +21 -0
- metadata +94 -52
- data/lib/jeka/jeka_helper.rb +0 -16
- data/lib/jeka/make.rb +0 -103
- data/test/example/01_bubble_sort/_algorithm.yaml +0 -12
- data/test/example/01_bubble_sort/_description.textile +0 -1
- data/test/example/01_bubble_sort/_references.textile +0 -1
- data/test/example/01_bubble_sort/_tests/test_01.yaml +0 -3
- data/test/example/01_bubble_sort/_tests/test_02.yaml +0 -3
- data/test/example/01_bubble_sort/cpp/_implementation.yaml +0 -9
- data/test/example/01_bubble_sort/ruby/_implementation.yaml +0 -6
- data/test/site/algorithm.textile +0 -27
- data/test/site/cpp.textile +0 -46
- data/test/site/ruby.textile +0 -28
- data/test/test_make.rb +0 -34
- data/test/test_test.rb +0 -16
data/lib/jeka.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
ROOT_PATH = File.expand_path(File.dirname(__FILE__))
|
2
2
|
|
3
|
-
require File.join(ROOT_PATH, '/jeka/
|
4
|
-
require File.join(ROOT_PATH, '/jeka/algorithm')
|
5
|
-
require File.join(ROOT_PATH, '/jeka/test')
|
3
|
+
require File.join(ROOT_PATH, '/jeka/compilers')
|
6
4
|
require File.join(ROOT_PATH, '/jeka/implementation')
|
7
|
-
require File.join(ROOT_PATH, '/jeka/
|
5
|
+
require File.join(ROOT_PATH, '/jeka/test')
|
6
|
+
require File.join(ROOT_PATH, '/jeka/algorithm')
|
7
|
+
require File.join(ROOT_PATH, '/jeka/test_case')
|
8
|
+
require File.join(ROOT_PATH, '/jeka/console')
|
9
|
+
require File.join(ROOT_PATH, '/jeka/analysis')
|
data/lib/jeka/algorithm.rb
CHANGED
@@ -1,38 +1,120 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
module Jeka
|
4
|
+
class Algorithm
|
4
5
|
|
5
|
-
|
6
|
+
attr_reader :database
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
jeka_reader :description
|
11
|
-
jeka_reader :references
|
8
|
+
def implementations
|
9
|
+
methods.select {|m| m =~ /^implementation_/}.map {|m| send(m)}
|
10
|
+
end
|
12
11
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def self.implementation(name)
|
13
|
+
imp = Implementation.new(name)
|
14
|
+
yield imp
|
15
|
+
define_method("implementation_#{name}".to_sym) do
|
16
|
+
return imp
|
17
|
+
end
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
20
|
+
def self.add_tests(test_dir)
|
21
|
+
Jeka::TestCase.reset
|
22
|
+
Dir.glob(test_dir).each do |d|
|
23
|
+
eval(File.open(d).readlines.join)
|
24
|
+
end
|
25
|
+
test_suites = Jeka::TestCase.test_suites
|
26
|
+
|
27
|
+
define_method(:test_suites) do
|
28
|
+
return test_suites
|
29
|
+
end
|
30
|
+
|
22
31
|
end
|
23
32
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
33
|
+
def jekafy
|
34
|
+
@database = Jeka::Analysis::Algorithm.create(
|
35
|
+
name: self.class.to_s,
|
36
|
+
implementations: implementations.collect {|imp| imp.jekafy},
|
37
|
+
test_cases: test_suites.collect {|tc| tc.jekafy}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def build(&block)
|
42
|
+
implementations.each do |imp|
|
43
|
+
b = imp.compiler.build
|
44
|
+
block.call(nil, :output, b[0]) if block_given?
|
45
|
+
block.call(nil, :error, b[1]) if block_given? and (not b[2] == 0)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def run(n=1, &block)
|
50
|
+
implementations.each do |imp|
|
51
|
+
test_suites.each do |ts|
|
52
|
+
ts.tests.each do |test|
|
53
|
+
n.times do
|
54
|
+
test_result = imp.compiler.run("#{test.input}\n")
|
55
|
+
block.call(nil, :output, test_result[0]) if block_given?
|
56
|
+
block.call(nil, :error, test_result[1]) if block_given? and (not test_result[2] == 0)
|
57
|
+
Jeka::Analysis::Result.create(
|
58
|
+
stdout: test_result[0].join,
|
59
|
+
stderr: test_result[1].join,
|
60
|
+
exit_status: test_result[2],
|
61
|
+
user_cpu_time: test_result[3][:user_cpu_time],
|
62
|
+
system_cpu_time: test_result[3][:system_cpu_time],
|
63
|
+
childrens_use_cpu_time: test_result[3][:childrens_use_cpu_time],
|
64
|
+
childrens_system_cpu_time: test_result[3][:childrens_system_cpu_time],
|
65
|
+
elapsed_real_time: test_result[3][:elapsed_real_time],
|
66
|
+
implementation: imp.database,
|
67
|
+
test: test.database
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
31
71
|
end
|
32
72
|
end
|
33
|
-
return @implementations
|
34
73
|
end
|
35
|
-
|
74
|
+
|
75
|
+
def self.reset
|
76
|
+
@@algorithms = {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.inherited(klass)
|
80
|
+
@@algorithms ||= {}
|
81
|
+
@@algorithms[klass] = true
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.algorithms
|
85
|
+
@@algorithms ||= {}
|
86
|
+
@@algorithms.keys.sort_by { |ts| ts.name }.collect{|ts| ts.new}
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.build_all(&block)
|
90
|
+
block.call(0, :step, "Building algorithms...") if block_given?
|
91
|
+
n = self.algorithms.length + 1
|
92
|
+
i = 0
|
93
|
+
self.algorithms.each do |alg|
|
94
|
+
i += 1
|
95
|
+
block.call(100*i/n, :step, "Building #{alg.class.to_s}") if block_given?
|
96
|
+
block_given? ? alg.build(&block) : alg.build
|
97
|
+
end
|
98
|
+
block.call(100, :done, "Done") if block_given?
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.run_all(n=1, &block)
|
102
|
+
Jeka::Analysis::Database.create(File.join(Dir.getwd, "analysis.jeka"))
|
103
|
+
block.call(0, :step, "Running algorithms...") if block_given?
|
104
|
+
s = self.algorithms.length + 1
|
105
|
+
i = 0
|
106
|
+
self.algorithms.each do |alg|
|
107
|
+
alg.jekafy
|
108
|
+
i += 1
|
109
|
+
block.call(100*i/s, :step, "Running #{alg.class.to_s}...") if block_given?
|
110
|
+
if block_given?
|
111
|
+
alg.run(n, &block)
|
112
|
+
else
|
113
|
+
alg.run(n)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
block.call(100, :done, "Done") if block_given?
|
117
|
+
end
|
118
|
+
|
36
119
|
end
|
37
|
-
|
38
|
-
end
|
120
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'data_mapper'
|
3
|
+
require 'dm-migrations'
|
4
|
+
|
5
|
+
|
6
|
+
require File.join(ROOT_PATH, 'jeka/analysis/database')
|
7
|
+
require File.join(ROOT_PATH, 'jeka/analysis/algorithm')
|
8
|
+
require File.join(ROOT_PATH, 'jeka/analysis/implementation')
|
9
|
+
require File.join(ROOT_PATH, 'jeka/analysis/implementation_information')
|
10
|
+
require File.join(ROOT_PATH, 'jeka/analysis/compiler')
|
11
|
+
require File.join(ROOT_PATH, 'jeka/analysis/compiler_option')
|
12
|
+
require File.join(ROOT_PATH, 'jeka/analysis/source_file')
|
13
|
+
require File.join(ROOT_PATH, 'jeka/analysis/test')
|
14
|
+
require File.join(ROOT_PATH, 'jeka/analysis/test_case')
|
15
|
+
require File.join(ROOT_PATH, 'jeka/analysis/result')
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class CompilerOption
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id , Serial
|
7
|
+
property :name, String
|
8
|
+
property :value, String
|
9
|
+
|
10
|
+
belongs_to :compiler
|
11
|
+
|
12
|
+
def self.convert(hash)
|
13
|
+
opt = []
|
14
|
+
hash.each do |key, value|
|
15
|
+
opt << CompilerOption.new(
|
16
|
+
name: key,
|
17
|
+
value: value
|
18
|
+
)
|
19
|
+
end
|
20
|
+
opt
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class Implementation
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
property :name, String
|
8
|
+
|
9
|
+
belongs_to :algorithm
|
10
|
+
has 1, :compiler
|
11
|
+
has n, :implementation_information
|
12
|
+
has n, :results
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class ImplementationInformation
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
property :name, String
|
8
|
+
property :value, String
|
9
|
+
|
10
|
+
belongs_to :implementation
|
11
|
+
|
12
|
+
def self.convert(hash)
|
13
|
+
info = []
|
14
|
+
hash.each do |key, value|
|
15
|
+
info << ImplementationInformation.new(
|
16
|
+
name: key,
|
17
|
+
value: value
|
18
|
+
)
|
19
|
+
end
|
20
|
+
info
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class Result
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id , Serial
|
7
|
+
property :stdout, String
|
8
|
+
property :stderr, String
|
9
|
+
property :exit_status, String
|
10
|
+
property :user_cpu_time, Float
|
11
|
+
property :system_cpu_time, Float
|
12
|
+
property :childrens_use_cpu_time, Float
|
13
|
+
property :childrens_system_cpu_time, Float
|
14
|
+
property :elapsed_real_time, Float
|
15
|
+
|
16
|
+
belongs_to :implementation
|
17
|
+
belongs_to :test
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Analysis
|
3
|
+
class SourceFile
|
4
|
+
include DataMapper::Resource
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
property :name, String
|
8
|
+
property :source, Text
|
9
|
+
|
10
|
+
belongs_to :compiler
|
11
|
+
|
12
|
+
def self.convert(array)
|
13
|
+
files = []
|
14
|
+
array.each do |file|
|
15
|
+
files << SourceFile.new(
|
16
|
+
name: File.basename(file),
|
17
|
+
source: File.open(file).readlines.join
|
18
|
+
)
|
19
|
+
end
|
20
|
+
files
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module Jeka
|
5
|
+
module Compiler
|
6
|
+
class Compiler
|
7
|
+
attr_reader :database
|
8
|
+
|
9
|
+
def command(cmd)
|
10
|
+
stdout_ = nil
|
11
|
+
stderr_ = nil
|
12
|
+
exit_status_ = nil
|
13
|
+
|
14
|
+
b = Benchmark.measure do
|
15
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
16
|
+
stdout_ = stdout.readlines
|
17
|
+
stderr_ = stderr.readlines
|
18
|
+
exit_status_ = wait_thr.value
|
19
|
+
end
|
20
|
+
end.to_a
|
21
|
+
|
22
|
+
bench = Hash.new
|
23
|
+
bench[:user_cpu_time] = b[1]
|
24
|
+
bench[:system_cpu_time] = b[2]
|
25
|
+
bench[:childrens_use_cpu_time] = b[3]
|
26
|
+
bench[:childrens_system_cpu_time] = b[4]
|
27
|
+
bench[:elapsed_real_time] = b[5]
|
28
|
+
return stdout_, stderr_, exit_status_.exitstatus, bench
|
29
|
+
end
|
30
|
+
|
31
|
+
def build(&block)
|
32
|
+
return _build_command ? command(_build_command) : [[], [], 0, 0]
|
33
|
+
end
|
34
|
+
|
35
|
+
def run(input = '')
|
36
|
+
return command("echo '#{input}' | #{_run_command}")
|
37
|
+
end
|
38
|
+
|
39
|
+
def jekafy
|
40
|
+
@database = Jeka::Analysis::Compiler.create(
|
41
|
+
name: self.class.to_s,
|
42
|
+
compiler_options: Jeka::Analysis::CompilerOption.convert(@options),
|
43
|
+
source_files: Jeka::Analysis::SourceFile.convert(@files)
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Jeka
|
2
|
+
module Compiler
|
3
|
+
|
4
|
+
class Gpp < Compiler
|
5
|
+
def initialize(files, options = {})
|
6
|
+
@files = files
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def _run_command
|
13
|
+
cmd = './' << @options[:o]
|
14
|
+
end
|
15
|
+
|
16
|
+
def _build_command
|
17
|
+
cmd = 'g++ '
|
18
|
+
@files.each do |f|
|
19
|
+
cmd << f << ' '
|
20
|
+
end
|
21
|
+
@options.each do |opt, value|
|
22
|
+
cmd << '-' << opt.to_s << ' ' << value
|
23
|
+
end
|
24
|
+
return cmd
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|