frypan 0.0.1 → 1.0.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/README.md +33 -0
- data/Rakefile +2 -0
- data/frypan.gemspec +3 -4
- data/lib/frypan.rb +191 -52
- data/lib/frypan/version.rb +1 -1
- data/tutorial/my_at.rb +17 -0
- data/tutorial/my_atd.rb +85 -0
- data/tutorial/sample_tcp_client.rb +8 -0
- data/tutorial/sample_tcp_server.rb +13 -0
- data/tutorial/tutorial.md +359 -0
- data/unit_test/test_frypan.rb +66 -0
- metadata +14 -14
- data/_README.md +0 -31
- data/bin/frypan +0 -55
- data/lib/frypan/database_sync_list.rb +0 -30
- data/lib/frypan/epg_parser.rb +0 -23
- data/lib/frypan/node.rb +0 -150
- data/lib/frypan/tuner.rb +0 -47
- data/unit_test/test_node.rb +0 -171
    
        data/_README.md
    DELETED
    
    | @@ -1,31 +0,0 @@ | |
| 1 | 
            -
            # Frypan
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            TODO: Write a gem description
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            ## Installation
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            Add this line to your application's Gemfile:
         | 
| 8 | 
            -
             | 
| 9 | 
            -
            ```ruby
         | 
| 10 | 
            -
            gem 'frypan'
         | 
| 11 | 
            -
            ```
         | 
| 12 | 
            -
             | 
| 13 | 
            -
            And then execute:
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                $ bundle
         | 
| 16 | 
            -
             | 
| 17 | 
            -
            Or install it yourself as:
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                $ gem install frypan
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            ## Usage
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            TODO: Write usage instructions here
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            ## Contributing
         | 
| 26 | 
            -
             | 
| 27 | 
            -
            1. Fork it ( https://github.com/[my-github-username]/frypan/fork )
         | 
| 28 | 
            -
            2. Create your feature branch (`git checkout -b my-new-feature`)
         | 
| 29 | 
            -
            3. Commit your changes (`git commit -am 'Add some feature'`)
         | 
| 30 | 
            -
            4. Push to the branch (`git push origin my-new-feature`)
         | 
| 31 | 
            -
            5. Create a new Pull Request
         | 
    
        data/bin/frypan
    DELETED
    
    | @@ -1,55 +0,0 @@ | |
| 1 | 
            -
            #!/usr/bin/env ruby
         | 
| 2 | 
            -
            # -*- coding: utf-8 -*-
         | 
| 3 | 
            -
            # -*- mode: ruby -*-
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            require 'mongo'
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            def install(home_path)
         | 
| 8 | 
            -
              # 1. mongodbのバイナリを落として [homepath]/mongodb.tarに保存
         | 
| 9 | 
            -
              # 2. 解凍する。[homepath]/mongodb/bin/mongodってな具合になる
         | 
| 10 | 
            -
              # 3. [homepath]/db/作る
         | 
| 11 | 
            -
            end
         | 
| 12 | 
            -
             | 
| 13 | 
            -
            def fork_db(home_path, port=27017)
         | 
| 14 | 
            -
              mongod = "#{home_path}/mongodb/bin/mongod"
         | 
| 15 | 
            -
              db = "#{home_path}/db/"
         | 
| 16 | 
            -
              log = "#{home_path}/db/server.log"
         | 
| 17 | 
            -
              status = `#{mongod} --dbpath #{db} --logpath #{log} --port #{port} --fork`
         | 
| 18 | 
            -
              pid = status.lines.map{|ln| ln.match(/forked process: (\d+)/)}.select{|a| a}.first[1].to_i
         | 
| 19 | 
            -
              success = status.lines.any?{|ln| ln.match(/successfully/)}
         | 
| 20 | 
            -
              if success then pid else nil end
         | 
| 21 | 
            -
            end
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            def connect_db(port=27017, host="localhost")
         | 
| 24 | 
            -
              Mongo::Connection.new(host, port).db("frypan_core")
         | 
| 25 | 
            -
            end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
            begin
         | 
| 28 | 
            -
              pid = fork_db("~/Workspace/")
         | 
| 29 | 
            -
              TinyFRP::Runtime.new(main_signal(connect_db)).run(:loop)
         | 
| 30 | 
            -
            ensure
         | 
| 31 | 
            -
              Process.kill("TERM", pid) if pid
         | 
| 32 | 
            -
            end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
            db = hoge
         | 
| 37 | 
            -
            api_server = APIServer.new(db) # fork webrick. only op-command throw.
         | 
| 38 | 
            -
            epg = hoge
         | 
| 39 | 
            -
            tuner = [fuga]
         | 
| 40 | 
            -
             | 
| 41 | 
            -
            command = TinyFRP.lift{ api_server.get_next_command } # one-unit-command OR nil
         | 
| 42 | 
            -
            current_time = TinyFRP.lift{ Time.now.strftime("%Y%m%d%H%M%S") }
         | 
| 43 | 
            -
            epg_flag = hoge
         | 
| 44 | 
            -
            tuners_flag = [fuga]
         | 
| 45 | 
            -
             | 
| 46 | 
            -
            main = TinyFRP::Bundle.new(command, current_time, epg_flag, tuners_flag) >> Node.top(setting)
         | 
| 47 | 
            -
             | 
| 48 | 
            -
            TinyFRP.loop(main) do |out|
         | 
| 49 | 
            -
              out[:reserve1].action(db)
         | 
| 50 | 
            -
              out[:reserve2].action(db)
         | 
| 51 | 
            -
              out[:reserve3].action(db)
         | 
| 52 | 
            -
              out[:reserve4].action(db)
         | 
| 53 | 
            -
              out[:epg].action(epg)
         | 
| 54 | 
            -
              out[:tuner1].action(tuner1)
         | 
| 55 | 
            -
            end
         | 
| @@ -1,30 +0,0 @@ | |
| 1 | 
            -
            module Frypan
         | 
| 2 | 
            -
              class DBSyncList
         | 
| 3 | 
            -
                def initialize(name, db)
         | 
| 4 | 
            -
                  @coll = db.collection(name)
         | 
| 5 | 
            -
                end
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                def +(list)
         | 
| 8 | 
            -
                  list.each{|a| @coll.insert(a)}
         | 
| 9 | 
            -
                  self
         | 
| 10 | 
            -
                end
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                def update(alt_list)
         | 
| 13 | 
            -
                  @coll.remove
         | 
| 14 | 
            -
                  alt_list.each{|a| @coll.insert(a)}
         | 
| 15 | 
            -
                  self
         | 
| 16 | 
            -
                end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                def update_elements(elements, ident_key)
         | 
| 19 | 
            -
                  elements.each do |a|
         | 
| 20 | 
            -
                    @coll.update({ident_key => a[ident_key]}, {"$set" => a}, true)
         | 
| 21 | 
            -
                  end
         | 
| 22 | 
            -
                  self
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                def to_a
         | 
| 26 | 
            -
                  @coll.find.to_a
         | 
| 27 | 
            -
                end
         | 
| 28 | 
            -
              end
         | 
| 29 | 
            -
            end
         | 
| 30 | 
            -
             | 
    
        data/lib/frypan/epg_parser.rb
    DELETED
    
    | @@ -1,23 +0,0 @@ | |
| 1 | 
            -
            module Frypan
         | 
| 2 | 
            -
              class EpgParser
         | 
| 3 | 
            -
                require 'm2ts_parser'
         | 
| 4 | 
            -
                class ParserProcess
         | 
| 5 | 
            -
                  def initialize(file_path)
         | 
| 6 | 
            -
                    
         | 
| 7 | 
            -
                  end
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                  def finished?
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  end
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                  def get_parsed
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                  end
         | 
| 16 | 
            -
                end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                def parse(file_path)
         | 
| 19 | 
            -
                  ParserProcess.new(file_path)
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
              end
         | 
| 22 | 
            -
            end
         | 
| 23 | 
            -
             | 
    
        data/lib/frypan/node.rb
    DELETED
    
    | @@ -1,150 +0,0 @@ | |
| 1 | 
            -
            module Frypan
         | 
| 2 | 
            -
              require 'tiny_frp'
         | 
| 3 | 
            -
              module Node
         | 
| 4 | 
            -
                def self.overlaped?(list_of_range)
         | 
| 5 | 
            -
                  !list_of_range.sort{|a, b| a.begin <=> b.begin}.each_cons(2).all?{|a, b| a.end <= b.begin}
         | 
| 6 | 
            -
                end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                def self.apply_operations(list, ops)
         | 
| 9 | 
            -
                  case
         | 
| 10 | 
            -
                  when ops == []
         | 
| 11 | 
            -
                    [list, ""]
         | 
| 12 | 
            -
                  when ops.first[:kind] == :add
         | 
| 13 | 
            -
                    added_list = list + [ops.first[:target]]
         | 
| 14 | 
            -
                    if overlaped?(added_list.map{|a| a[:start_time]..a[:end_time]})
         | 
| 15 | 
            -
                      [nil, "cannot add reservation: #{ops.first[:target]}"]
         | 
| 16 | 
            -
                    else
         | 
| 17 | 
            -
                      apply_operations(added_list, ops.drop(1))
         | 
| 18 | 
            -
                    end
         | 
| 19 | 
            -
                  when ops.first[:kind] == :remove
         | 
| 20 | 
            -
                    if list.find{|a| a[:start_time] == ops.first[:target][:start_time]}
         | 
| 21 | 
            -
                      apply_operations(list.reject{|a| a[:start_time] == ops.first[:target][:start_time]}, ops.drop(1))
         | 
| 22 | 
            -
                    else
         | 
| 23 | 
            -
                      [nil, "unexist remove reservation id: #{ops.first[:target][:id]}"]
         | 
| 24 | 
            -
                    end
         | 
| 25 | 
            -
                  else
         | 
| 26 | 
            -
                    [nil, "unknown operation '#{ops.first[:kind]}'"]
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
                end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                def self.ReserveListFoldp(tuner_id, initial_list=[])
         | 
| 31 | 
            -
                  TinyFRP.foldp(launch: nil, list: initial_list, ack: nil) do |acc, command, current_time|
         | 
| 32 | 
            -
                    case
         | 
| 33 | 
            -
                    when command && command[:target_tuner] == tuner_id
         | 
| 34 | 
            -
                      new_list, status = *apply_operations(acc[:list], command[:operations])
         | 
| 35 | 
            -
                      ack = command.merge({
         | 
| 36 | 
            -
                         timestamp: current_time,
         | 
| 37 | 
            -
                         succeeded: !!new_list,
         | 
| 38 | 
            -
                         status: status
         | 
| 39 | 
            -
                       })
         | 
| 40 | 
            -
                      if new_list
         | 
| 41 | 
            -
                        {launch: nil, list: new_list.sort{|a, b| a[:start_time] <=> b[:start_time]}, ack: ack}
         | 
| 42 | 
            -
                      else
         | 
| 43 | 
            -
                        {launch: nil, ack: ack}
         | 
| 44 | 
            -
                      end
         | 
| 45 | 
            -
                    when acc[:list] != [] && acc[:list].first[:start_time] <= current_time
         | 
| 46 | 
            -
                      {launch: acc[:list].first, list: acc[:list].drop(1), ack: nil}
         | 
| 47 | 
            -
                    else
         | 
| 48 | 
            -
                      {launch: nil, ack: nil}
         | 
| 49 | 
            -
                    end
         | 
| 50 | 
            -
                  end
         | 
| 51 | 
            -
                end
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                def self.PersistantReserveListFoldp(tuner_id, dbsync_reserve)
         | 
| 54 | 
            -
                  TinyFRP.foldp(last_list: nil, list: dbsync_reserve) do |acc, rlist|
         | 
| 55 | 
            -
                    if !acc[:last_list] || acc[:last_list] != rlist[:list]
         | 
| 56 | 
            -
                      {last_list: rlist[:list], list: acc[:list].update(rlist[:list])}
         | 
| 57 | 
            -
                    else
         | 
| 58 | 
            -
                      {}
         | 
| 59 | 
            -
                    end
         | 
| 60 | 
            -
                  end
         | 
| 61 | 
            -
                end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                def self.RecordingAsyncFoldp(tuner)
         | 
| 64 | 
            -
                  TinyFRP.foldp(busy: false, rec_process: nil, waiting: [], log: []) do |acc, rlist|
         | 
| 65 | 
            -
                    case
         | 
| 66 | 
            -
                    when rlist[:launch]
         | 
| 67 | 
            -
                      {waiting: acc[:waiting] + [rlist[:launch]], log: []}
         | 
| 68 | 
            -
                    when acc[:busy]
         | 
| 69 | 
            -
                      {busy: !acc[:rec_process].finished?, log: acc[:rec_process].get_log}
         | 
| 70 | 
            -
                    when acc[:waiting] != []
         | 
| 71 | 
            -
                      {
         | 
| 72 | 
            -
                        busy:        true,
         | 
| 73 | 
            -
                        rec_process: tuner.rec(acc[:waiting].first),
         | 
| 74 | 
            -
                        waiting:     acc[:waiting].drop(1),
         | 
| 75 | 
            -
                        log:         []
         | 
| 76 | 
            -
                      }
         | 
| 77 | 
            -
                    else
         | 
| 78 | 
            -
                      {log: []}
         | 
| 79 | 
            -
                    end
         | 
| 80 | 
            -
                  end
         | 
| 81 | 
            -
                end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                def self.RecordingLogFoldp(initial_log=[])
         | 
| 84 | 
            -
                  TinyFRP.foldp(log: initial_log, epg_order: [], recorded: []) do |acc, *log_inputs|
         | 
| 85 | 
            -
                    if log_inputs.any?{|a| a != []}
         | 
| 86 | 
            -
                      new_logs = log_inputs.select{|a| a != []}.flatten
         | 
| 87 | 
            -
                      {
         | 
| 88 | 
            -
                        log:       acc[:log] + new_logs,
         | 
| 89 | 
            -
                        epg_order: Fnc.find_epg_order(new_logs),
         | 
| 90 | 
            -
                        recorded:  Fnc.find_recorded(new_logs)
         | 
| 91 | 
            -
                      }
         | 
| 92 | 
            -
                    else
         | 
| 93 | 
            -
                      {epg_order: [], recorded: []}
         | 
| 94 | 
            -
                    end
         | 
| 95 | 
            -
                  end
         | 
| 96 | 
            -
                end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                def self.EpgExtractAsyncFoldp(epg_parser)
         | 
| 99 | 
            -
                  TinyFRP.foldp(busy: false, parser_process: nil, waiting: [], extracted: []) do |acc, log|
         | 
| 100 | 
            -
                    case
         | 
| 101 | 
            -
                    when log[:epg_order]
         | 
| 102 | 
            -
                      {waiting: acc[:waiting] + [log[:epg_order]], extracted: []}
         | 
| 103 | 
            -
                    when acc[:busy]
         | 
| 104 | 
            -
                      {busy: !acc[:parser_process].finished?, extracted: acc[:parser_process].get_parsed}
         | 
| 105 | 
            -
                    when acc[:waiting] != []
         | 
| 106 | 
            -
                      {
         | 
| 107 | 
            -
                        busy:           true,
         | 
| 108 | 
            -
                        parser_process: epg_parser.parse(acc[:waiting].first[:file_path]), 
         | 
| 109 | 
            -
                        waiting:        acc[:waiting].drop(1),
         | 
| 110 | 
            -
                        extracted:      []
         | 
| 111 | 
            -
                      }
         | 
| 112 | 
            -
                    else
         | 
| 113 | 
            -
                      {extracted: []}
         | 
| 114 | 
            -
                    end
         | 
| 115 | 
            -
                  end
         | 
| 116 | 
            -
                end
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                def self.ProgramListFoldp(initial_list=[])
         | 
| 119 | 
            -
                  TinyFRP.foldp(list: initial_list) do |acc, epg|
         | 
| 120 | 
            -
                    if epg[:extracted] != []
         | 
| 121 | 
            -
                      # epg[:extracted] := list of {program_id: [service_id, event_id], ...}
         | 
| 122 | 
            -
                      {list: acc[:list].update_elements(epg[:extracted], :program_id)}
         | 
| 123 | 
            -
                    else
         | 
| 124 | 
            -
                      {}
         | 
| 125 | 
            -
                    end
         | 
| 126 | 
            -
                  end
         | 
| 127 | 
            -
                end
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                def self.RecordedListFoldp(initial_list=[])
         | 
| 130 | 
            -
                  TinyFRP.foldp(list: initial_list) do |acc, log|
         | 
| 131 | 
            -
                    if log[:recorded] != []
         | 
| 132 | 
            -
                      {list: acc[:list] + log[:recorded]}
         | 
| 133 | 
            -
                    else
         | 
| 134 | 
            -
                      {}
         | 
| 135 | 
            -
                    end
         | 
| 136 | 
            -
                  end
         | 
| 137 | 
            -
                end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                def self.UIresponseFoldp(initial_list=[])
         | 
| 140 | 
            -
                  TinyFRP.foldp(list: initial_list) do |acc, current_time, *acks|
         | 
| 141 | 
            -
                    if acks.any?{|a| a}
         | 
| 142 | 
            -
                      {list: acc[:list] + acks.select{|a| a}}
         | 
| 143 | 
            -
                    else
         | 
| 144 | 
            -
                      {}
         | 
| 145 | 
            -
                    end
         | 
| 146 | 
            -
                  end
         | 
| 147 | 
            -
                end
         | 
| 148 | 
            -
              end
         | 
| 149 | 
            -
            end
         | 
| 150 | 
            -
             | 
    
        data/lib/frypan/tuner.rb
    DELETED
    
    | @@ -1,47 +0,0 @@ | |
| 1 | 
            -
            module Frypan
         | 
| 2 | 
            -
              class Tuner
         | 
| 3 | 
            -
                class RecordingProcess
         | 
| 4 | 
            -
                  def initialize(command)
         | 
| 5 | 
            -
                    @reader, writer = IO.pipe
         | 
| 6 | 
            -
                    @pid = Process.spawn(command, :err => writer, :out => writer)
         | 
| 7 | 
            -
                    @mutex = Mutex.new
         | 
| 8 | 
            -
                    @logs = []
         | 
| 9 | 
            -
                    Thread.new{
         | 
| 10 | 
            -
                      while IO::select([@reader])
         | 
| 11 | 
            -
                        @mutex.synchronize{
         | 
| 12 | 
            -
                          @logs << @reader.gets.chomp
         | 
| 13 | 
            -
                        }
         | 
| 14 | 
            -
                      end
         | 
| 15 | 
            -
                    }
         | 
| 16 | 
            -
                  end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                  def finished?
         | 
| 19 | 
            -
                    @finished ||= Process.waitpid2(@pid, Process::WNOHANG)
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                  def get_log
         | 
| 23 | 
            -
                    res = []
         | 
| 24 | 
            -
                    @mutex.synchronize{
         | 
| 25 | 
            -
                      res = @logs.dup
         | 
| 26 | 
            -
                      @logs = []
         | 
| 27 | 
            -
                    }
         | 
| 28 | 
            -
                    res
         | 
| 29 | 
            -
                  end
         | 
| 30 | 
            -
                end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                def initialize(format_str)
         | 
| 33 | 
            -
                  @format_str = format_str
         | 
| 34 | 
            -
                end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
                def rec(setting)
         | 
| 37 | 
            -
                  RecordingProcess.new(Tuner.make_command(@format_str, setting))
         | 
| 38 | 
            -
                end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                def self.make_command(format_str, setting)
         | 
| 41 | 
            -
                  setting.keys.inject(format_str) do |str, key|
         | 
| 42 | 
            -
                    str.gsub("<#{key}>", setting[key].to_s)
         | 
| 43 | 
            -
                  end
         | 
| 44 | 
            -
                end
         | 
| 45 | 
            -
              end
         | 
| 46 | 
            -
            end
         | 
| 47 | 
            -
             | 
    
        data/unit_test/test_node.rb
    DELETED
    
    | @@ -1,171 +0,0 @@ | |
| 1 | 
            -
            $LIBRARY_ROOT_PATH = File.dirname(File.expand_path(File.dirname(__FILE__)))
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module Frypan
         | 
| 4 | 
            -
              module UnitTest
         | 
| 5 | 
            -
                require 'test/unit'
         | 
| 6 | 
            -
                require $LIBRARY_ROOT_PATH + '/lib/frypan/node.rb'
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                class DummyList
         | 
| 9 | 
            -
                  attr_reader :array
         | 
| 10 | 
            -
                  def initialize(init=[])
         | 
| 11 | 
            -
                    @array = []
         | 
| 12 | 
            -
                  end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  def +(list)
         | 
| 15 | 
            -
                    DummyList.new(@array + list)
         | 
| 16 | 
            -
                  end
         | 
| 17 | 
            -
             | 
| 18 | 
            -
                  def update(alt_list)
         | 
| 19 | 
            -
                    DummyList.new(alt_list)
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                  def update_elements(elements, ident_key)
         | 
| 23 | 
            -
                    if elements == []
         | 
| 24 | 
            -
                      self
         | 
| 25 | 
            -
                    else
         | 
| 26 | 
            -
                      update_element(elements.first, ident_key).update_elements(elements.drop(1), ident_key)
         | 
| 27 | 
            -
                    end
         | 
| 28 | 
            -
                  end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                  def update_element(element, ident_key)
         | 
| 31 | 
            -
                    if @array.find{|a| a[ident_key] == element[ident_key]}
         | 
| 32 | 
            -
                      DummyList.new(@array.map{|a| a[ident_key] == element[ident_key] ? element : a})
         | 
| 33 | 
            -
                    else
         | 
| 34 | 
            -
                      DummyList.new(@array + [element])
         | 
| 35 | 
            -
                    end
         | 
| 36 | 
            -
                  end
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                class DummyTuner
         | 
| 40 | 
            -
                  class DummyRecordingProcess
         | 
| 41 | 
            -
                    def initialize(logs)
         | 
| 42 | 
            -
                      @logs = logs.dup
         | 
| 43 | 
            -
                    end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                    def finished?
         | 
| 46 | 
            -
                      @logs.empty?
         | 
| 47 | 
            -
                    end
         | 
| 48 | 
            -
                    
         | 
| 49 | 
            -
                    def get_log
         | 
| 50 | 
            -
                      @logs.shift || []
         | 
| 51 | 
            -
                    end
         | 
| 52 | 
            -
                  end
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                  def initialize(logs)
         | 
| 55 | 
            -
                    @logs = logs
         | 
| 56 | 
            -
                  end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                  def rec(setting)
         | 
| 59 | 
            -
                    DummyRecordingProcess.new(@logs)
         | 
| 60 | 
            -
                  end
         | 
| 61 | 
            -
                end
         | 
| 62 | 
            -
             | 
| 63 | 
            -
                class DummyEpgParser
         | 
| 64 | 
            -
                  class DummyParserProcess
         | 
| 65 | 
            -
                    def initialize(parseds)
         | 
| 66 | 
            -
                      @parseds = parseds.dup
         | 
| 67 | 
            -
                    end
         | 
| 68 | 
            -
             | 
| 69 | 
            -
                    def finished?
         | 
| 70 | 
            -
                      @parseds.empty?
         | 
| 71 | 
            -
                    end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                    def get_parsed
         | 
| 74 | 
            -
                      @parseds.shift || []
         | 
| 75 | 
            -
                    end
         | 
| 76 | 
            -
                  end
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                  def initialize(parseds)
         | 
| 79 | 
            -
                    @parseds = parseds
         | 
| 80 | 
            -
                  end
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                  def parse(file_path)
         | 
| 83 | 
            -
                    DummyParserProcess.new(@parseds)
         | 
| 84 | 
            -
                  end
         | 
| 85 | 
            -
                end
         | 
| 86 | 
            -
             | 
| 87 | 
            -
                module Util
         | 
| 88 | 
            -
                  def mkcom(command_id, target_tuner, *ops)
         | 
| 89 | 
            -
                    {command_id: command_id, target_tuner: target_tuner, operations: ops}
         | 
| 90 | 
            -
                  end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                  def mkop(kind, target)
         | 
| 93 | 
            -
                    {kind: kind, target: target}
         | 
| 94 | 
            -
                  end
         | 
| 95 | 
            -
                  
         | 
| 96 | 
            -
                  def mkres(id, start_time, end_time)
         | 
| 97 | 
            -
                    {id: id, start_time: start_time, end_time: end_time}
         | 
| 98 | 
            -
                  end
         | 
| 99 | 
            -
                end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                class NodeTest < Test::Unit::TestCase
         | 
| 102 | 
            -
                  include Util
         | 
| 103 | 
            -
             | 
| 104 | 
            -
                  def test_ReserveListFoldp
         | 
| 105 | 
            -
                    n = Node.ReserveListFoldp(:test_tuner, [])
         | 
| 106 | 
            -
                    vals = [
         | 
| 107 | 
            -
                            nil,
         | 
| 108 | 
            -
                            com1 = mkcom(0, :test_tuner, mkop(:add, res1 = mkres(0, 2, 5))),
         | 
| 109 | 
            -
                            com2 = mkcom(1, :test_tuner, mkop(:add, res2 = mkres(1, 5, 7))),
         | 
| 110 | 
            -
                            nil,
         | 
| 111 | 
            -
                            com3 = mkcom(2, :test_tuner, mkop(:add, res3 = mkres(2, 6, 10)))
         | 
| 112 | 
            -
                           ].each_with_index.map{|a, i| n.call(a, i)}
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                    assert_equal({launch: nil, list: [], ack: nil}, vals[0])
         | 
| 115 | 
            -
             | 
| 116 | 
            -
                    expect_ack1 = com1.merge(timestamp: 1, succeeded: true, status: "")
         | 
| 117 | 
            -
                    assert_equal({launch: nil,  list: [res1], ack: expect_ack1}, vals[1])
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                    expect_ack2 = com2.merge(timestamp: 2, succeeded: true, status: "")
         | 
| 120 | 
            -
                    assert_equal({launch: nil, list: [res1, res2], ack: expect_ack2}, vals[2])
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                    assert_equal({launch: res1,  list: [res2], ack: nil}, vals[3])
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                    expect_ack3 = com3.merge(timestamp: 4, succeeded: false, status: vals[4][:ack][:status])
         | 
| 125 | 
            -
                    assert_equal({launch: nil, list: [res2], ack: expect_ack3}, vals[4])
         | 
| 126 | 
            -
                  end
         | 
| 127 | 
            -
             | 
| 128 | 
            -
                  def test_PersistantReserveListFoldp
         | 
| 129 | 
            -
                    n = Node.PersistantReserveListFoldp(:tuner_tuner, DummyList.new([]))
         | 
| 130 | 
            -
                    vals = [
         | 
| 131 | 
            -
                            {list: [:a]},
         | 
| 132 | 
            -
                            {list: [:a]},
         | 
| 133 | 
            -
                            {list: [:a, :b]},
         | 
| 134 | 
            -
                           ].map{|a| n.call(a)}
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                    assert_equal(vals[0], vals[1])
         | 
| 137 | 
            -
                    assert_not_equal(vals[1], vals[2])
         | 
| 138 | 
            -
                  end
         | 
| 139 | 
            -
             | 
| 140 | 
            -
                  def test_RecordingAsyncFoldp
         | 
| 141 | 
            -
                    n = Node.RecordingAsyncFoldp(DummyTuner.new([[0, 1], [2]]))
         | 
| 142 | 
            -
                    v = [
         | 
| 143 | 
            -
                         {launch: nil},
         | 
| 144 | 
            -
                         {launch: :a},
         | 
| 145 | 
            -
                         {launch: nil},
         | 
| 146 | 
            -
                         {launch: :b},
         | 
| 147 | 
            -
                         {launch: nil},
         | 
| 148 | 
            -
                         {launch: nil},
         | 
| 149 | 
            -
                         {launch: nil},
         | 
| 150 | 
            -
                         {launch: nil},
         | 
| 151 | 
            -
                         {launch: nil},
         | 
| 152 | 
            -
                         {launch: nil},
         | 
| 153 | 
            -
                         {launch: nil},
         | 
| 154 | 
            -
                        ].map{|a| n.call(a)}
         | 
| 155 | 
            -
             | 
| 156 | 
            -
                    assert_equal({busy: false, rec_process: v[0][:rec_process],  waiting: [],   log: []},     v[0])
         | 
| 157 | 
            -
                    assert_equal({busy: false, rec_process: v[1][:rec_process],  waiting: [:a], log: []},     v[1])
         | 
| 158 | 
            -
                    assert_equal({busy: true,  rec_process: v[2][:rec_process],  waiting: [],   log: []},     v[2])
         | 
| 159 | 
            -
                    assert_equal({busy: true,  rec_process: v[3][:rec_process],  waiting: [:b], log: []},     v[3])
         | 
| 160 | 
            -
                    assert_equal({busy: true,  rec_process: v[4][:rec_process],  waiting: [:b], log: [0, 1]}, v[4])
         | 
| 161 | 
            -
                    assert_equal({busy: true,  rec_process: v[5][:rec_process],  waiting: [:b], log: [2]},    v[5])
         | 
| 162 | 
            -
                    assert_equal({busy: false, rec_process: v[6][:rec_process],  waiting: [:b], log: []},     v[6])
         | 
| 163 | 
            -
                    assert_equal({busy: true,  rec_process: v[7][:rec_process],  waiting: [],   log: []},     v[7])
         | 
| 164 | 
            -
                    assert_equal({busy: true,  rec_process: v[8][:rec_process],  waiting: [],   log: [0, 1]}, v[8])
         | 
| 165 | 
            -
                    assert_equal({busy: true,  rec_process: v[9][:rec_process],  waiting: [],   log: [2]},    v[9])
         | 
| 166 | 
            -
                    assert_equal({busy: false, rec_process: v[10][:rec_process], waiting: [],   log: []},     v[10])
         | 
| 167 | 
            -
                  end
         | 
| 168 | 
            -
                end
         | 
| 169 | 
            -
              end
         | 
| 170 | 
            -
            end
         | 
| 171 | 
            -
             |