asautotest 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+ # flash-policy-server --- simple Flash security policy file server
4
+ # Copyright (C) 2010 Go Interactive
5
+
6
+ # This file is part of ASAutotest.
7
+
8
+ # ASAutotest is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+
13
+ # ASAutotest is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with ASAutotest. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ require "socket"
22
+ require "timeout"
23
+
24
+ class PolicyServer
25
+ PORT = 843
26
+
27
+ def initialize
28
+ @server = TCPServer.new(PORT)
29
+ @server.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
30
+
31
+ info "Listening to localhost:#{PORT}."
32
+ end
33
+
34
+ def run
35
+ loop { accept }
36
+ end
37
+
38
+ def accept
39
+ handle_socket(@server.accept)
40
+ end
41
+
42
+ def info(message)
43
+ puts info_string(message)
44
+ end
45
+
46
+ def info_string(message)
47
+ "policy-server: #{message}"
48
+ end
49
+
50
+ def begin_info(message)
51
+ STDOUT.print info_string("#{message}...")
52
+ STDOUT.flush
53
+ end
54
+
55
+ def end_info(message)
56
+ STDOUT.puts " #{message}."
57
+ end
58
+
59
+ EXPECTED_REQUEST = "<policy-file-request/>\0"
60
+
61
+ def handle_socket(socket)
62
+ source = "#{socket.peeraddr[2]}:#{socket.peeraddr[1]}"
63
+ begin_info "Serving #{source}"
64
+ request = Timeout.timeout(3) { socket.read(EXPECTED_REQUEST.size) }
65
+ if request == EXPECTED_REQUEST
66
+ socket.print(policy_xml)
67
+ socket.print("\0")
68
+ end_info "ok"
69
+ else
70
+ end_info "recieved garbage: #{request.inspect}"
71
+ end
72
+ rescue Timeout::Error
73
+ end_info "timeout"
74
+ ensure
75
+ socket.close
76
+ end
77
+
78
+ def policy_xml
79
+ <<-end_xml
80
+ <cross-domain-policy>
81
+ <site-control permitted-cross-domain-policies="master-only"/>
82
+ <allow-access-from domain="*" to-ports="*"/>
83
+ </cross-domain-policy>
84
+ end_xml
85
+ end
86
+ end
87
+
88
+ PolicyServer.new.run
@@ -0,0 +1,115 @@
1
+ # -*- coding: utf-8 -*-
2
+ # compilation-output-parser.rb --- parse the output of one compilation
3
+ # Copyright (C) 2010 Go Interactive
4
+
5
+ # This file is part of ASAutotest.
6
+
7
+ # ASAutotest is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ASAutotest is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ASAutotest. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module ASAutotest
21
+ class OutputParser
22
+ def initialize(output, request, stopwatch, result)
23
+ @output = output
24
+ @request = request
25
+ @stopwatch = stopwatch
26
+ @result = result
27
+
28
+ @problematic_file_names = Set.new
29
+ @n_problems = 0
30
+ end
31
+
32
+ def self.parse(*arguments)
33
+ new(*arguments).run
34
+ end
35
+
36
+ def run
37
+ parse_lines
38
+ add_summary
39
+ end
40
+
41
+ def parse_lines
42
+ @result.source_directories = @request.source_directories
43
+
44
+ while has_more_lines?
45
+ line = read_line
46
+ puts ">> #{line}" if Logging.verbose?
47
+ parse_line(line)
48
+ end
49
+ end
50
+
51
+ def parse_line(line)
52
+ case line
53
+ when /^Loading configuration file /
54
+ when /^fcsh: Assigned (\d+) as the compile target id/
55
+ @request.compile_id = $1
56
+ when /^Recompile: /
57
+ when /^Reason: /
58
+ when /^\s*$/
59
+ when /\(\d+ bytes\)$/
60
+ @successful = true
61
+ when /^Nothing has changed /
62
+ @n_recompiled_files = 0
63
+ when /^Files changed: (\d+) Files affected: (\d+)/
64
+ @n_recompiled_files = $1.to_i + $2.to_i
65
+ when /^(.*?)\((\d+)\): col: (\d+) (.*)/
66
+ file_name = $1
67
+ line_number = $2.to_i
68
+ column_number = $3.to_i - 1
69
+ message = $4
70
+ source_line = read_lines(4)[1]
71
+
72
+ location = Location[line_number, column_number, source_line]
73
+ problem = Problem[message, location]
74
+
75
+ add_problem(file_name, problem)
76
+ when /^Error: (.*)/
77
+ add_problem(nil, Problem[$1, nil])
78
+ when /^(.*?): (.*)/
79
+ add_problem($1, Problem[$2, nil])
80
+ else
81
+ @result.add_unrecognized_line(line)
82
+ end
83
+ end
84
+
85
+ def add_problem(file_name, problem)
86
+ @first_problem ||= problem
87
+ @problematic_file_names << file_name
88
+ @n_problems += 1
89
+ @result.add_problem(file_name, problem)
90
+ end
91
+
92
+ def add_summary
93
+ @result.add_summary \
94
+ :request => @request,
95
+ :successful? => @successful,
96
+ :n_recompiled_files => @n_recompiled_files,
97
+ :n_problematic_files => @problematic_file_names.size,
98
+ :n_problems => @n_problems,
99
+ :first_problem => @first_problem,
100
+ :compilation_time => @stopwatch
101
+ end
102
+
103
+ def has_more_lines?
104
+ not @output.empty?
105
+ end
106
+
107
+ def read_lines(n)
108
+ @output.shift(n).map(&:chomp)
109
+ end
110
+
111
+ def read_line
112
+ @output.shift.chomp
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,102 @@
1
+ # -*- coding: utf-8 -*-
2
+ # compilation-result.rb --- collect the results of a compilation
3
+ # Copyright (C) 2010 Go Interactive
4
+
5
+ # This file is part of ASAutotest.
6
+
7
+ # ASAutotest is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ASAutotest is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ASAutotest. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module ASAutotest
21
+ class CompilationResult
22
+ attr_reader :n_recompiled_files
23
+ attr_reader :problematic_files
24
+ attr_reader :unrecognized_lines
25
+ attr_reader :summaries
26
+
27
+ def initialize
28
+ @problematic_files = {}
29
+ @n_recompiled_files = nil
30
+ @unrecognized_lines = []
31
+ @summaries = []
32
+ end
33
+
34
+ # ----------------------------------------------------
35
+
36
+ def source_directories= value
37
+ @source_directories = value
38
+ end
39
+
40
+ def add_problem(file_name, problem)
41
+ get_problematic_file(file_name) << problem unless
42
+ @typing == :dynamic and problem.type_warning?
43
+ end
44
+
45
+ def get_problematic_file(file_name)
46
+ if @problematic_files.include? file_name
47
+ @problematic_files[file_name]
48
+ else
49
+ @problematic_files[file_name] =
50
+ ProblematicFile.new(file_name, @source_directories)
51
+ end
52
+ end
53
+
54
+ # ----------------------------------------------------
55
+
56
+ def add_unrecognized_line(line)
57
+ @unrecognized_lines << line
58
+ end
59
+
60
+ def add_summary(summary)
61
+ @summaries << summary
62
+ end
63
+
64
+ # ----------------------------------------------------
65
+
66
+ def any_type_warnings?
67
+ @problematic_files.values.any? &:any_type_warnings?
68
+ end
69
+
70
+ def successful?
71
+ @summaries.all? { |x| x[:successful?] }
72
+ end
73
+
74
+ def n_problematic_files
75
+ @problematic_files.values.size
76
+ end
77
+
78
+ def n_problems
79
+ @problematic_files.values.inject(0) { |a, x| a + x.n_problems }
80
+ end
81
+
82
+ def failed?
83
+ not successful?
84
+ end
85
+
86
+ def bootstrap?
87
+ @summaries.all? { |x| x[:n_recompiled_files] == nil }
88
+ end
89
+
90
+ def n_recompiled_files
91
+ @summaries.inject(0) { |a, x| a + x[:n_recompiled_files] }
92
+ end
93
+
94
+ def recompilation?
95
+ not bootstrap?
96
+ end
97
+
98
+ def did_anything?
99
+ bootstrap? or n_recompiled_files > 0
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,135 @@
1
+ # -*- coding: utf-8 -*-
2
+ # compilation-runner.rb --- run compilations and report the results
3
+ # Copyright (C) 2010 Go Interactive
4
+
5
+ # This file is part of ASAutotest.
6
+
7
+ # ASAutotest is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ASAutotest is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ASAutotest. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ require "asautotest/logging"
21
+
22
+ module ASAutotest
23
+ class CompilationRunner
24
+ class CompilationFailure < Exception ; end
25
+
26
+ include Logging
27
+
28
+ attr_reader :result
29
+
30
+ def initialize(shell, options)
31
+ @shell = shell
32
+ @typing = options[:typing]
33
+ @result = CompilationResult.new
34
+ end
35
+
36
+ def run
37
+ @stopwatch = Stopwatch.new
38
+ whisper_commands
39
+ compile
40
+ @stopwatch.stop
41
+ print_report
42
+ end
43
+
44
+ def whisper_commands
45
+ for command in @shell.compilation_commands
46
+ whisper "$ #{command}"
47
+ end
48
+ end
49
+
50
+ def compile
51
+ say("Compiling") do |status|
52
+ @shell.run_compilations(@result)
53
+
54
+ if @result.failed?
55
+ status << "failed"
56
+ elsif @result.did_anything?
57
+ files = if @result.bootstrap?
58
+ "everything"
59
+ else
60
+ n_x(@result.n_recompiled_files, "file")
61
+ end
62
+ status << "recompiled #{files} in #{compilation_time}"
63
+ else
64
+ status << "nothing changed"
65
+ end
66
+
67
+ if @result.successful?
68
+ for summary in @result.summaries
69
+ title = File.basename(summary[:request].source_file_name)
70
+ if summary[:successful?] and summary[:n_recompiled_files] != 0
71
+ files = if summary[:n_recompiled_files]
72
+ n_x(summary[:n_recompiled_files], "file")
73
+ else
74
+ "everything"
75
+ end
76
+ time = "#{summary[:compilation_time].to_s(1)}s"
77
+ growl_success title, "Compiled #{files} in #{time}."
78
+ end
79
+ end
80
+ else
81
+ summary = @result.summaries.find { |x| not x[:successful?] }
82
+ file_name = summary[:first_problem].file.basename
83
+ line_number = summary[:first_problem].line_number
84
+ message = summary[:first_problem].plain_message
85
+ growl_error "#{file_name}, line #{line_number}", message
86
+ end
87
+ end
88
+ end
89
+
90
+ def n_x(n, x)
91
+ "#{n} #{x}#{n == 1 ? "" : "s"}"
92
+ end
93
+
94
+ def growl_success(title, message)
95
+ if ASAutotest::growl_enabled
96
+ options = { :title => title, :icon => "as" }
97
+ if ASAutotest::displaying_growl_error
98
+ options[:identifier] = GROWL_ERROR_TOKEN
99
+ ASAutotest::displaying_growl_error = false
100
+ end
101
+ Growl.notify(message, options)
102
+ end
103
+ end
104
+
105
+ def growl_error(title, message)
106
+ if ASAutotest::growl_enabled
107
+ Growl.notify_error message,
108
+ :title => title, :sticky => true,
109
+ :identifier => GROWL_ERROR_TOKEN
110
+ ASAutotest::displaying_growl_error = true
111
+ end
112
+ end
113
+
114
+ def compilation_time
115
+ "~#{@stopwatch.to_s(1)} seconds"
116
+ end
117
+
118
+ def print_report
119
+ for line in @result.unrecognized_lines
120
+ barf line
121
+ end
122
+
123
+ for name, file in @result.problematic_files
124
+ file.print_report
125
+ end
126
+
127
+ puts unless @result.problematic_files.empty?
128
+
129
+ if @typing == nil and @result.any_type_warnings?
130
+ hint "Use --dynamic-typing to disable type declaration warnings,"
131
+ hint "or --static-typing to disable this hint."
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,78 @@
1
+ # -*- coding: utf-8 -*-
2
+ # compiler-shell.rb --- wrapper around the fcsh executable
3
+ # Copyright (C) 2010 Go Interactive
4
+
5
+ # This file is part of ASAutotest.
6
+
7
+ # ASAutotest is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ASAutotest is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ASAutotest. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module ASAutotest
21
+ class CompilerShell
22
+ PROMPT = "\n(fcsh) "
23
+
24
+ class PromptNotFound < Exception ; end
25
+
26
+ include Logging
27
+
28
+ attr_reader :compilation_requests
29
+
30
+ def initialize(options)
31
+ @compilation_requests = options[:compilation_requests]
32
+ end
33
+
34
+ def start
35
+ say "Starting compiler shell" do
36
+ @process = IO.popen("#{FCSH} 2>&1", "r+")
37
+ read_until_prompt
38
+ end
39
+ rescue PromptNotFound => error
40
+ shout "Could not find FCSH prompt:"
41
+ for line in error.message.lines do
42
+ barf line.chomp
43
+ end
44
+ if error.message.include? "command not found"
45
+ shout "Please make sure that fcsh is in your PATH."
46
+ shout "Alternatively, set the ‘FCSH’ environment variable."
47
+ end
48
+ exit -1
49
+ end
50
+
51
+ def run_compilations(result)
52
+ for request in @compilation_requests
53
+ run_compilation(request, result)
54
+ end
55
+ end
56
+
57
+ def compilation_commands
58
+ @compilation_requests.map { |x| x.compilation_command }
59
+ end
60
+
61
+ def run_compilation(request, result)
62
+ stopwatch = Stopwatch.new
63
+ @process.puts(request.compilation_command)
64
+ OutputParser.parse(read_until_prompt, request, stopwatch, result)
65
+ stopwatch.stop
66
+ end
67
+
68
+ def read_until_prompt
69
+ result = ""
70
+ until result.include? PROMPT
71
+ result << @process.readpartial(100)
72
+ end
73
+ result.lines.entries[0 .. -2]
74
+ rescue EOFError
75
+ raise PromptNotFound, result
76
+ end
77
+ end
78
+ end