device_api 1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 55ea06db2435c33d959c62aab352305c35a32864
4
+ data.tar.gz: 80d93f31e0607100e755fe6de7e97520a4486af9
5
+ SHA512:
6
+ metadata.gz: e87c848043acf6f36d74a72a1e0ac6c698de8bb7fe4018444a43b561049ba86a04da195c155c1180366d9984b0e6e748b07b86e6ba5363ae0823b017a02be13e
7
+ data.tar.gz: 685aef3c25dcca463f9435146be72214eebfd7e61347bdbb52a12fad57db28bffe083923d503ffa177a365b4877aa6df47d2c0e2021da89965cd92f1727a861c
data/.gitignore ADDED
@@ -0,0 +1,38 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
35
+
36
+ # rubymine
37
+ .idea
38
+
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'rspec'
5
+ end
6
+
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.2.5)
5
+ rspec (3.0.0)
6
+ rspec-core (~> 3.0.0)
7
+ rspec-expectations (~> 3.0.0)
8
+ rspec-mocks (~> 3.0.0)
9
+ rspec-core (3.0.2)
10
+ rspec-support (~> 3.0.0)
11
+ rspec-expectations (3.0.2)
12
+ diff-lcs (>= 1.2.0, < 2.0)
13
+ rspec-support (~> 3.0.0)
14
+ rspec-mocks (3.0.2)
15
+ rspec-support (~> 3.0.0)
16
+ rspec-support (3.0.2)
17
+
18
+ PLATFORMS
19
+ ruby
20
+
21
+ DEPENDENCIES
22
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 BBC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # DeviceAPI
2
+
3
+ *DeviceAPI* is a collection of gems that make working with physical devices easy
4
+ and consistent. *DeviceAPI* provides common utilities such as device detection
5
+ and identification, and useful helpers for installing applications and
6
+ identifying problems with devices.
7
+
8
+ We use *DeviceAPI* heavily to leverage devices in *Hive CI*. It’s also used by
9
+ our test developers in their test code. It’s our interface to the devices we
10
+ test against and is where we put all common code for interacting with our
11
+ physical devices. It also provides an abstraction so we can deal with devices
12
+ interchangeably.
13
+
14
+ This is the base gem on which all *DeviceAPI* gems are built. It contains the
15
+ common execution and logging methods, and the base Device class.
16
+
17
+ ## Testing
18
+
19
+ Tests are written in rspec, you can run them with:
20
+ bundle install
21
+ bundle exec rspec
22
+
23
+ ## Creating a new DeviceAPI Gem
24
+
25
+ *DeviceAPI* gems should take a consistent approach to their api where possible.
26
+
27
+ A new *DeviceApi* gem should, as a minimum, include a detection method on the
28
+ class. For example, a DeviceAPI implementation for TVs:
29
+
30
+ DeviceAPI::TV.devices
31
+
32
+ ... should return an array of device objects of type DeviceAPI::TV.
33
+
34
+ You should consider adding a way to directly detect a specific device, for
35
+ example using the serial:
36
+
37
+ DeviceAPI::TV.device( serial_id )
38
+
39
+ The device object should contain all accessors to the physical device
40
+ information:
41
+
42
+ device.class #=> DeviceAPI::TV
43
+ device.model #=> 'sony'
44
+ device.serial # => 'a221s3144cc23'
45
+
46
+ And also expose functionality through the same object:
47
+
48
+ device.reboot()
49
+
50
+ ## License
51
+
52
+ ## License
53
+
54
+ *DeviceAPI* is available to everyone under the terms of the MIT open source
55
+ licence. Take a look at the LICENSE file in the code.
56
+
57
+ Copyright (c) 2015 BBC
@@ -0,0 +1,13 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'device_api'
3
+ s.version = '1.0.1'
4
+ s.date = Time.now.strftime("%Y-%m-%d")
5
+ s.summary = 'Physical Device Management API'
6
+ s.description = 'A common interface for physical devices'
7
+ s.authors = ['BBC', 'David Buckhurst']
8
+ s.email = 'david.buckhurst@bbc.co.uk'
9
+ s.files = `git ls-files`.split "\n"
10
+ s.homepage = 'https://github.com/bbc/device_api'
11
+ s.license = 'MIT'
12
+ s.add_development_dependency 'rspec'
13
+ end
data/lib/device_api.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'device_api/sys_log'
2
+
3
+ module DeviceAPI
4
+ attr_accessor :log
5
+
6
+ @@log = DeviceAPI::SysLog.new
7
+
8
+ def self.set_logger(log)
9
+ @@log = log
10
+ end
11
+
12
+ def self.log
13
+ @@log
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ # Encoding: utf-8
2
+ module DeviceAPI
3
+ class Device
4
+ attr_accessor :serial
5
+ end
6
+ end
@@ -0,0 +1,79 @@
1
+ # Encoding: utf-8
2
+ require 'open3'
3
+ require 'ostruct'
4
+ require 'timeout'
5
+ require 'device_api'
6
+
7
+ module DeviceAPI
8
+ # Provides method to execute terminal commands in a reusable way
9
+ class Execution
10
+
11
+ # execute_with_timeout_and_retry constants
12
+ COMMAND_TIMEOUT = 30 # base number of seconds to wait until adb command times out
13
+ COMMAND_RETRIES = 5 # number of times we will retry the adb command.
14
+ # actual maximum seconds waited before timeout is
15
+ # (1 * s) + (2 * s) + (3 * s) ... up to (n * s)
16
+ # where s = COMMAND_TIMEOUT
17
+ # n = COMMAND_RETRIES
18
+
19
+ # Execute out to shell
20
+ # Returns a struct collecting the execution results
21
+ # struct = DeviceAPI::ADB.execute( 'adb devices' )
22
+ # struct.stdout #=> "std out"
23
+ # struct.stderr #=> ''
24
+ # strict.exit #=> 0
25
+ def self.execute(command)
26
+ result = OpenStruct.new
27
+
28
+ stdout, stderr, status = Open3.capture3(command)
29
+
30
+ result.exit = status.exitstatus
31
+ result.stdout = stdout
32
+ result.stderr = stderr
33
+
34
+ result
35
+ end
36
+
37
+ # Execute a command with retries if the command fails to return
38
+ def self.execute_with_timeout_and_retry(command)
39
+ retries_left = COMMAND_RETRIES
40
+ cmd_successful = false
41
+ result = 0
42
+
43
+ while (retries_left > 0) and (cmd_successful == false) do
44
+ begin
45
+ ::Timeout.timeout(COMMAND_TIMEOUT) do
46
+ result = execute(command)
47
+ cmd_successful = true
48
+ end
49
+ rescue ::Timeout::Error
50
+ retries_left -= 1
51
+ if retries_left > 0
52
+ DeviceAPI.log.error "Command #{command} timed out after #{COMMAND_TIMEOUT.to_s} sec, retrying,"\
53
+ + " #{retries_left.to_s} attempts left.."
54
+ end
55
+ end
56
+ end
57
+
58
+ if retries_left < COMMAND_RETRIES # if we had to retry
59
+ if cmd_successful == false
60
+ msg = "Command #{command} timed out after #{COMMAND_RETRIES.to_s} retries. !"\
61
+ + " Exiting.."
62
+ DeviceAPI.log.fatal(msg)
63
+ raise DeviceAPI::CommandTimeoutError.new(msg)
64
+ else
65
+ DeviceAPI.log.info "Command #{command} succeeded execution after retrying"
66
+ end
67
+ end
68
+
69
+ result
70
+ end
71
+ end
72
+
73
+ class CommandTimeoutError < StandardError
74
+ def initialize(msg)
75
+ super(msg)
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,39 @@
1
+ require 'syslog'
2
+
3
+ module DeviceAPI
4
+ class SysLog
5
+
6
+ attr_accessor :syslog
7
+
8
+ def log(priority,message)
9
+ if @syslog and @syslog.opened?
10
+ @syslog = Syslog.reopen('device-api-gem', Syslog::LOG_PID, Syslog::LOG_DAEMON)
11
+ else
12
+ @syslog = Syslog.open('device-api-gem', Syslog::LOG_PID, Syslog::LOG_DAEMON)
13
+ end
14
+
15
+ @syslog.log(priority,message)
16
+ @syslog.close
17
+ end
18
+
19
+ def fatal(message)
20
+ self.log(Syslog::LOG_CRIT,message)
21
+ end
22
+
23
+ def error(message)
24
+ self.log(Syslog::LOG_ERR,message)
25
+ end
26
+
27
+ def warn(message)
28
+ self.log(Syslog::LOG_WARNING,message)
29
+ end
30
+
31
+ def info(message)
32
+ self.log(Syslog::LOG_INFO,message)
33
+ end
34
+
35
+ def debug(message)
36
+ self.log(Syslog::LOG_DEBUG,message)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ $LOAD_PATH.unshift('./lib/')
2
+
3
+ require 'device_api/execution'
4
+
5
+ include RSpec
6
+
7
+ ProcessStatusStub = Struct.new(:exitstatus)
8
+ $STATUS_ZERO = ProcessStatusStub.new(0)
9
+
10
+ describe DeviceAPI::Execution do
11
+ describe '.execute' do
12
+
13
+ before(:all) do
14
+ @result = DeviceAPI::Execution.execute('echo boo')
15
+ end
16
+
17
+ it 'returns an OpenStruct execution result' do
18
+ expect(@result).to be_a OpenStruct
19
+ end
20
+
21
+ it 'captures exit value in hash' do
22
+ expect(@result.exit).to eq(0)
23
+ end
24
+
25
+ it 'captures stdout in hash' do
26
+ expect(@result.stdout).to eq("boo\n")
27
+ end
28
+
29
+ it 'capture stderr in hash' do
30
+ expect(@result.stderr).to eq('')
31
+ end
32
+
33
+ end
34
+
35
+ describe '.execute_with_timeout_and_retry' do
36
+ it 'should raise an exception if the command takes too long to execute' do
37
+ stub_const('DeviceAPI::Execution::COMMAND_TIMEOUT',1)
38
+ stub_const('DeviceAPI::Execution::COMMAND_RETRIES',1)
39
+ sleep_time = 5
40
+ cmd = "sleep #{sleep_time.to_s}"
41
+ expect { DeviceAPI::Execution.execute_with_timeout_and_retry(cmd) }.to raise_error(DeviceAPI::CommandTimeoutError)
42
+ end
43
+
44
+ it 'should execute successfully if command returns before the timeout' do
45
+ stub_const('DeviceAPI::Execution::COMMAND_TIMEOUT',2)
46
+ stub_const('DeviceAPI::Execution::COMMAND_RETRIES',5)
47
+ sleep_time = 1
48
+ cmd = "sleep #{sleep_time.to_s}"
49
+ DeviceAPI::Execution.execute_with_timeout_and_retry(cmd)
50
+ end
51
+
52
+ end
53
+
54
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: device_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - BBC
8
+ - David Buckhurst
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-05-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ description: A common interface for physical devices
29
+ email: david.buckhurst@bbc.co.uk
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".gitignore"
35
+ - Gemfile
36
+ - Gemfile.lock
37
+ - LICENSE
38
+ - README.md
39
+ - device_api.gemspec
40
+ - lib/device_api.rb
41
+ - lib/device_api/device.rb
42
+ - lib/device_api/execution.rb
43
+ - lib/device_api/sys_log.rb
44
+ - spec/execution_spec.rb
45
+ homepage: https://github.com/bbc/device_api
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.4.5
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Physical Device Management API
69
+ test_files: []
70
+ has_rdoc: