Skip to content

Commit

Permalink
Rng + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JBlackN committed Sep 11, 2015
1 parent 751d881 commit 3c710b9
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 6 deletions.
10 changes: 5 additions & 5 deletions lib/budik.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
require 'commander/import'
require 'fileutils'
#require 'json'
#require 'net/http'
require 'net/http'
#require 'open3'
require 'r18n-core'
require 'singleton'
#require 'socket'
#require 'uri'
require 'socket'
require 'uri'
require 'ya2yaml'
require 'yaml'
require 'youtube_addy'
Expand All @@ -19,7 +19,7 @@
require './lib/budik/config'
#require './budik/devices.rb'
#require './budik/player.rb'
#require './budik/rng.rb'
require './lib/budik/rng'
require './lib/budik/sources'
require './lib/budik/version'

Expand Down Expand Up @@ -48,7 +48,7 @@ module Budik
c.syntax = 'Budík.rb run [options]'
c.summary = 'DEFAULT: Runs alarm.'
c.description = 'Runs alarm with specified options. CLI options > options.yml.'
c.option '-c', '--categories [array]', Array, 'Limit selection by categories. Example usage: "cat1.subcat1 cat2.subcat1.subsubcat1 .excludethis.subcat etc."'
c.option '-c', '--categories [string]', String, 'Limit selection by categories. Example usage: "cat1.subcat1 cat2.subcat1.subsubcat1 .excludethis.subcat etc."'
c.option '-d', '--download-method [string]', String, 'Override download method set in your active options.'
c.option '-n', '--number [integer]', Integer, 'Override selection using random number generator by specifying fixed number.'
c.option '-p', '--player [string]', String, 'Override which player to use.'
Expand Down
4 changes: 4 additions & 0 deletions lib/budik/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ def self.command_config(_args, opts)
end

def self.command_run(_args, opts)
config = Config.instance
config.load(opts)

sources_path = config.options['sources']['path']
Sources.instance.parse(sources_path, opts.categories)
end

def self.command_set(_args, opts)
Expand Down
91 changes: 91 additions & 0 deletions lib/budik/rng.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
module Budik
class Rng
include Singleton

def generate(items, method_override = nil)
options = Config.instance.options['rng']

if method_override != nil
method = method_override
else
method = options['method']
end

case method
when 'hwrng'
hwrng(options['hwrng'], items)
when 'random.org'
random_org(options['random.org'], items)
when 'rand-hwrng-seed'
swrng(items, hwrng(options['hwrng'], 2**64))
when 'rand'
swrng(items)
else
puts 'Invalid RNG method specified. Using rand() with default seed.'
swrng(items)
end
end

private

def hwrng(options, items)
begin
source = File.new(options['source'], 'r')
max = 2**64
threshold = (max - items) % items
number = source.read(8).unpack('Q')
while number.first < threshold do
number = source.read(8).unpack('Q')
end
number.first % items
rescue
puts "Error: Couldn't obtain random number from #{options['source']}."
puts 'Falling back to rand() with default seed.'
swrng(items)
end
end

def random_org(options, items)
uri = URI.parse('http://api.random.org/json-rpc/1/invoke')
header = { 'Content-Type' => 'application/json-rpc' }
data = {
jsonrpc: '2.0',
method: 'generateIntegers',
params: {
apiKey: options['apikey'],
n: 1,
min: 0,
max: items
},
id: 29
}

http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = data.to_json

begin
response = http.request(request)
rescue
puts "Error: Couldn't obtain random number from Random.org."
puts 'Falling back to rand() with default seed.'
swrng(items)
end

if response.code.to_i == 200
JSON.parse(response.body)['result']['random']['data'].first
else
puts "Error: Couldn't obtain random number from Random.org."
puts "Response code: #{response.code}."
puts "Response body: #{response.body}."
puts 'Falling back to rand() with default seed.'
swrng(items)
end
end

def swrng(items, seed = nil)
seed == nil ? srand : srand(seed) # TODO: Test this
rand(0...items)
end
end
end
53 changes: 53 additions & 0 deletions spec/lib/budik/rng_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require 'singleton'
require 'spec_helper'

require 'budik/rng'

describe Budik::Rng, '#generate' do
context 'using hwrng' do
it 'generates random number' do
config = Budik::Config.instance
config.load(Hash.new)

config.options['rng']['hwrng']['source'] = '/dev/hwrng'
5.times do
num = Budik::Rng.instance.generate(100, 'hwrng')
expect(num >= 0 && num <= 100).to eq true
end

config.options['rng']['hwrng']['source'] = '/dev/random'
5.times do
num = Budik::Rng.instance.generate(100, 'hwrng')
expect(num >= 0 && num <= 100).to eq true
end

config.options['rng']['hwrng']['source'] = '/dev/urandom'
100.times do
num = Budik::Rng.instance.generate(100, 'hwrng')
expect(num >= 0 && num <= 100).to eq true
end
end
end

context 'using random.org' do
it 'generates random number' do
config = Budik::Config.instance
config.load(Hash.new)

if config.options['rng']['random.org']['apikey']
num = Budik::Rng.instance.generate(100, 'random.org')
expect(num >= 0 && num <= 100).to eq true
end
end
end

context 'using srand' do
it 'generates random number' do
100.times do
num = Budik::Rng.instance.generate(100, 'rand')
expect(num >= 0 && num <= 100).to eq true
end
end
end
end

1 change: 0 additions & 1 deletion spec/lib/budik/sources_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#require 'r18n-core'
require 'fileutils'
require 'singleton'
require 'spec_helper'
Expand Down

0 comments on commit 3c710b9

Please sign in to comment.