hive-runner-ios 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 21392f8328f698d89ed6fc4a48fa7b136b7cba6e
4
+ data.tar.gz: 1e9121c47f1317f7e2c2da79ecac0bc23a2c1208
5
+ SHA512:
6
+ metadata.gz: 21656ea02cab268e6eb98b20707639c67c87f7086ab5a303d3272d56046f2539e5fecfb5a9387615493f9a47a04a047ddbfe451077916ef3438d3ec762b5646e
7
+ data.tar.gz: 1d70d6e1c672a0bdedcb3355dc1459c076452d1e62fc90ae98dfdf1835b63bf09e643ac7576ed133e22ce1327eb16fb62beb3d802992be6602d14031be64f98c
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # hive-runner-ios
2
+
3
+ iOS component for the hive-runner
4
+
5
+ ## Quick start
6
+
7
+ Install the hive-runner and setup your hive as described in the [hive-runner Readme](https://github.com/bbc/hive-runner/blob/master/README.md).
8
+
9
+ When presented with the option of adding a module, do so and enter 'ios' as the module name, select yes to retrieve from Github and enter BBC as the account name.
10
+
11
+ ## Configuration file
12
+
13
+ The configuration file allows you to specify the Development Team, Provisioning Certificate, Signing Identity and Bundle ID to use when testing your app, please change these as appropriate:
14
+
15
+ ios:
16
+ provisioning_cert: iOS Team Provisioning Profile: *
17
+ development_team: DEVELOPMENT_TEAM_ID
18
+ signing_identity: iPhone Developer
19
+ bundle_id: TEST_APP
@@ -0,0 +1,171 @@
1
+ require 'hive/controller'
2
+ require 'hive/worker/ios'
3
+ require 'device_api/ios'
4
+
5
+ module Hive
6
+ class Controller
7
+ class Ios < Controller
8
+
9
+ def detect
10
+ Hive.logger.debug("#{Time.now} Polling hive: #{Hive.id}")
11
+ Hive.devicedb('Hive').poll(Hive.id)
12
+ Hive.logger.debug("#{Time.now} Finished polling hive: #{Hive.id}")
13
+ devices = DeviceAPI::IOS.devices
14
+
15
+ Hive.logger.debug('No devices attached') if devices.empty?
16
+ Hive.logger.debug("#{Time.now} Retrieving hive details")
17
+ hive_details = Hive.devicedb('Hive').find(Hive.id)
18
+ Hive.logger.debug("#{Time.now} Finished retrieving hive details")
19
+
20
+ unless hive_details.key?('devices')
21
+ Hive.logger.debug('Could not connect to DeviceDB at this time')
22
+ return []
23
+ end
24
+
25
+ unless hive_details['devices'].empty?
26
+ hive_details['devices'].select {|a| a['os'] == 'ios'}.each do |device|
27
+ registered_device = devices.select { |a| a.serial == device['serial'] }
28
+ if registered_device.empty?
29
+ # A previously registered device isn't attached
30
+ Hive.logger.debug("Removing previously registered device - #{device}")
31
+ Hive.devicedb('Device').hive_disconnect(device['id'])
32
+ else
33
+ # A previously registered device is attached, poll it
34
+ Hive.logger.debug("#{Time.now} Polling attached device - #{device}")
35
+ Hive.devicedb('Device').poll(device['id'])
36
+ Hive.logger.debug("#{Time.now} Finished polling device - #{device}")
37
+
38
+ populate_queues(device)
39
+ devices = devices - registered_device
40
+ end
41
+ end
42
+ end
43
+
44
+ display_untrusted(devices)
45
+ display_devices
46
+
47
+ if hive_details.key?('devices')
48
+ hive_details['devices'].select {|a| a['os'] == 'ios'}.collect do |device|
49
+ object = Object
50
+ @device_class.split('::').each { |sub| object = object.const_get(sub) }
51
+ object.new(@config.merge(device))
52
+ end
53
+ else
54
+ []
55
+ end
56
+ end
57
+
58
+ def display_untrusted(devices)
59
+ untrusted_devices = []
60
+ # We will now have a list of devices that haven't previously been added
61
+ devices.each do |device|
62
+ begin
63
+ if !device.trusted?
64
+ untrusted_devices << device.serial
65
+ next
66
+ end
67
+
68
+ register_new_device(device)
69
+ end
70
+ end
71
+
72
+ if !untrusted_devices.empty?
73
+ puts Terminal::Table.new headings: ['Untrusted Devices'], rows: [untrusted_devices]
74
+ end
75
+ end
76
+
77
+ def display_devices
78
+ rows = []
79
+
80
+ hive_details = Hive.devicedb('Hive').find(Hive.id)
81
+ if hive_details.key?('devices')
82
+ unless hive_details['devices'].empty?
83
+ rows = hive_details['devices'].map do |device|
84
+ [
85
+ "#{device['device_brand']} #{device['device_model']}",
86
+ device['serial'],
87
+ (device['device_queues'].map { |queue| queue['name']}).join("\n"),
88
+ device['status']
89
+ ]
90
+ end
91
+ end
92
+ end
93
+ table = Terminal::Table.new :headings => ['Device', 'Serial', 'Queue Name', 'Status'], :rows => rows
94
+
95
+ puts(table)
96
+ end
97
+
98
+ def register_new_device(device)
99
+ Hive.logger.debug("Found iOS device: #{device.model}")
100
+
101
+ attributes = {
102
+ os: 'ios',
103
+ os_version: device.version,
104
+ serial: device.serial,
105
+ device_type: device.type,
106
+ device_model: device.model.to_s.gsub(',','_'),
107
+ device_range: device.device_class,
108
+ device_brand: 'Apple',
109
+ hive: Hive.id
110
+ }
111
+
112
+ registration = Hive.devicedb('Device').register(attributes)
113
+ Hive.devicedb('Device').hive_connect(registration['id'], Hive.id)
114
+ end
115
+
116
+ def populate_queues(device)
117
+ queues = calculate_queue_names(device)
118
+
119
+ devicedb_queues = device['device_queues'].map { |d| d['name'] }
120
+ # Check to see if the queues have already been registered with this device
121
+ missing_queues = (queues - devicedb_queues) + (devicedb_queues - queues)
122
+ return if missing_queues.empty?
123
+
124
+ queues << missing_queues
125
+
126
+ queue_ids = queues.flatten.uniq.map { |queue| find_or_create_queue(queue) }
127
+
128
+ values = {
129
+ name: device['name'],
130
+ hive_id: device['hive_id'],
131
+ feature_list: device['features'],
132
+ device_queue_ids: queue_ids
133
+ }
134
+
135
+ Hive.devicedb('Device').edit(device['id'], values)
136
+ end
137
+
138
+ def find_or_create_queue(name)
139
+ queue = Hive.devicedb('Queue').find_by_name(name)
140
+ return queue.first['id'] unless queue.empty?
141
+
142
+ create_queue(name, "#{name} queue created by Hive Runner")['id']
143
+ end
144
+
145
+ def create_queue(name, description)
146
+ queue_attributes = {
147
+ name: name,
148
+ description: description
149
+ }
150
+
151
+ Hive.devicedb('Queue').register(device_queue: queue_attributes )
152
+ end
153
+
154
+ def calculate_queue_names(device)
155
+
156
+ queues = [
157
+ device['device_model'],
158
+ device['os'],
159
+ "#{device['os']}-#{device['os_version']}",
160
+ "#{device['os']}-#{device['os_version']}-#{device['device_model']}",
161
+ device['device_type'],
162
+ "#{device['os']}-#{device['device_type']}"
163
+ ]
164
+
165
+ queues << device["features"] unless device["features"].empty?
166
+
167
+ queues.flatten
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,12 @@
1
+ require 'hive/device'
2
+
3
+ module Hive
4
+ class Device
5
+ class Ios < Device
6
+ def initialize(config)
7
+ @identity = config['id']
8
+ super
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ require 'hive/messages'
2
+
3
+ module Hive
4
+ module Messages
5
+ class IosJob < Hive::Messages::Job
6
+ def build
7
+ self.target.symbolize_keys[:build]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,125 @@
1
+ require 'hive/worker'
2
+ require 'hive/messages/ios_job'
3
+ require 'fruity_builder'
4
+
5
+ module Hive
6
+ class PortReserver
7
+ attr_accessor :ports
8
+ def initialize
9
+ self.ports = {}
10
+ end
11
+
12
+ def reserve(queue_name)
13
+ self.ports[queue_name] = yield
14
+ self.ports[queue_name]
15
+ end
16
+ end
17
+
18
+ class Worker
19
+ class Ios < Worker
20
+
21
+ attr_accessor :device
22
+
23
+ def initialize(device)
24
+ @worker_ports = PortReserver.new
25
+ self.device = device
26
+ super(device)
27
+ end
28
+
29
+ def alter_project(project_path)
30
+ dev_team = @options['development_team'] || ''
31
+ signing_identity = @options['signing_identity'] || ''
32
+ provisioning_profile = @options['provisioning_profile'] || ''
33
+
34
+ helper = FruityBuilder::IOS::Helper.new(project_path)
35
+
36
+ helper.build.replace_bundle_id(@options['bundle_id'])
37
+
38
+ helper.build.replace_dev_team(dev_team)
39
+ helper.build.replace_code_sign_identity(signing_identity)
40
+ helper.build.replace_provisioning_profile(provisioning_profile)
41
+ helper.build.save_project_properties
42
+ end
43
+
44
+ def replace_project_data(options = {})
45
+ regex = Regexp.new(options[:regex])
46
+ replacements = options[:data].scan(regex).uniq.flatten
47
+
48
+ result = options[:data]
49
+ replacements.each do |to_replace|
50
+ result = result.gsub(to_replace, options[:new_value])
51
+ end
52
+
53
+ result
54
+ end
55
+
56
+ def pre_script(job, file_system, script)
57
+ Hive.devicedb('Device').poll(@options['id'], 'busy')
58
+
59
+ if job.build
60
+ FileUtils.mkdir(file_system.home_path + '/build')
61
+ app_path = file_system.home_path + '/build/' + 'build.ipa'
62
+
63
+ file_system.fetch_build(job.build, app_path)
64
+ app_info = DeviceAPI::IOS::Plistutil.get_bundle_id_from_app(app_path)
65
+ app_bundle = app_info['CFBundleIdentifier']
66
+ script.set_env 'BUNDLE_ID', app_bundle
67
+ else
68
+ alter_project(file_system.home_path + '/test_code/code/')
69
+ end
70
+
71
+ ip_address = DeviceAPI::IOS::IPAddress.address(self.device['serial'])
72
+
73
+ script.set_env 'CHARLES_PROXY_PORT', @ports.reserve(queue_name: 'Charles')
74
+
75
+ # TODO: Allow the scheduler to specify the ports to use
76
+
77
+ script.set_env 'APPIUM_PORT', @worker_ports.reserve(queue_name: 'Appium') { self.allocate_port }
78
+ script.set_env 'BOOTSTRAP_PORT', @worker_ports.reserve(queue_name: 'Bootstrap') { self.allocate_port }
79
+ script.set_env 'CHROMEDRIVER_PORT', @worker_ports.reserve(queue_name: 'Chromedriver') { self.allocate_port }
80
+
81
+ script.set_env 'APP_PATH', app_path
82
+ script.set_env 'APP_BUNDLE_PATH', app_path
83
+ script.set_env 'DEVICE_TARGET', self.device['serial']
84
+ script.set_env 'DEVICE_ENDPOINT', "http://#{ip_address}:37265"
85
+
86
+ "#{self.device['serial']} #{@ports.ports['Appium']} #{app_path} #{file_system.results_path}"
87
+ end
88
+
89
+ def job_message_klass
90
+ Hive::Messages::IosJob
91
+ end
92
+
93
+ def post_script(job, file_system, script)
94
+ @log.info('Post script')
95
+ @worker_ports.ports.each do |name, port|
96
+ self.release_port(port)
97
+ end
98
+ set_device_status('idle')
99
+ end
100
+
101
+ def device_status
102
+ details = Hive.devicedb('Device').find(@options['id'])
103
+ if details.key?('status')
104
+ @state = details['status']
105
+ else
106
+ @state
107
+ end
108
+ end
109
+
110
+ def set_device_status(status)
111
+ @state = status
112
+ begin
113
+ details = Hive.devicedb('Device').poll(@options['id'], status)
114
+ if details.key?('status')
115
+ @state = details['status']
116
+ else
117
+ @state
118
+ end
119
+ rescue
120
+ @state
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hive-runner-ios
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jon Wilson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: device_api-ios
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fruity_builder
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: The iOS controller module for Hive Runner
42
+ email: jon.wilson01@bbc.co.uk
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - README.md
48
+ - lib/hive/controller/ios.rb
49
+ - lib/hive/device/ios.rb
50
+ - lib/hive/messages/ios_job.rb
51
+ - lib/hive/worker/ios.rb
52
+ homepage: https://github.com/bbc/hive-runner-ios
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 2.4.8
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: Hive Runner iOS
76
+ test_files: []