Skip to content

Commit

Permalink
Merge pull request #119 from VKCOM/di/ios-provider/file-and-logs/QA-1…
Browse files Browse the repository at this point in the history
…6207

Di/ios provider/file and logs/qa 16207
  • Loading branch information
DaniilSmirnov authored Feb 13, 2025
2 parents dbe78da + e32d87e commit 757572f
Show file tree
Hide file tree
Showing 15 changed files with 311 additions and 130 deletions.
5 changes: 4 additions & 1 deletion lib/units/ios-device/support/storage.js → lib/units/base-device/support/storage.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import request from 'postman-request'
import logger from '../../../util/logger.js'
export default syrup.serial()
.define(options => {
const log = logger.createLogger('ios-device:support:storage')
const log = logger.createLogger('device:support:storage')
let plugin = Object.create(null)
plugin.store = function(type, stream, meta) {
let resolver = Promise.defer()
let args = {
url: url.resolve(options.storageUrl, util.format('s/upload/%s', type))
, headers: {
internal: 'Internal ' + meta.jwt
}
}
let req = request.post(args, function(err, res, body) {
if (err) {
Expand Down
2 changes: 1 addition & 1 deletion lib/units/device/plugins/filesystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import wireutil from '../../../wire/util.js'
import adb from '../support/adb.js'
import router from '../../base-device/support/router.js'
import push from '../../base-device/support/push.js'
import storage from '../support/storage.js'
import storage from '../../base-device/support/storage.js'
export default syrup.serial()
.dependency(adb)
.dependency(router)
Expand Down
2 changes: 1 addition & 1 deletion lib/units/device/plugins/screen/capture.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import wireutil from '../../../../wire/util.js'
import adb from '../../support/adb.js'
import router from '../../../base-device/support/router.js'
import push from '../../../base-device/support/push.js'
import storage from '../../support/storage.js'
import storage from '../../../base-device/support/storage.js'
import minicap from '../../resources/minicap.js'
import display from '../util/display.js'
export default syrup.serial()
Expand Down
47 changes: 0 additions & 47 deletions lib/units/device/support/storage.js

This file was deleted.

4 changes: 3 additions & 1 deletion lib/units/ios-device/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import wda from './plugins/wda.js'
import push from '../base-device/support/push.js'
import sub from '../base-device/support/sub.js'
import group from './plugins/group.js'
import storage from './support/storage.js'
import storage from '../base-device/support/storage.js'
import devicelog from './plugins/devicelog.js'
import stream from './plugins/screen/stream.js'
import install from './plugins/install.js'
import reboot from './plugins/reboot.js'
import clipboard from './plugins/clipboard.js'
import remotedebug from './plugins/remotedebug.js'
import filesystem from './plugins/filesystem.js'
export default (function(options) {
// Show serial number in logs
logger.setGlobalIdentifier(options.serial)
Expand All @@ -39,6 +40,7 @@ export default (function(options) {
.dependency(reboot)
.dependency(clipboard)
.dependency(remotedebug)
.dependency(filesystem)
.define(function(options, heartbeat, solo, info, wda) {
if (process.send) {
process.send('ready')
Expand Down
83 changes: 73 additions & 10 deletions lib/units/ios-device/plugins/devicelog.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import push from '../../base-device/support/push.js'
import router from '../../base-device/support/router.js'
import sub from '../../base-device/support/sub.js'
import group from './group.js'
import {IncompleteJsonParser} from 'incomplete-json-parser'

export default syrup
.serial()
export default syrup.serial()
.dependency(push)
.dependency(router)
.dependency(sub)
.dependency(group)
.define(function(options, push, router, group) {
.define(function(options, push, router, sub, group) {
const log = logger.createLogger('device:plugins:devicelog')

let DeviceLogger = {
Expand All @@ -31,17 +31,79 @@ export default syrup
, startLogging: async function(channel) {
DeviceLogger.setChannel(channel)
try {
DeviceLogger.stream = spawn('idb logs --udid ' + options.serial, {shell: true})
const realGroup = await group.get()
const parser = new IncompleteJsonParser()

DeviceLogger.stream = spawn('idb', ['log', '--udid', options.serial, '--', '--style', 'json'])

DeviceLogger.stream.stdout.on('data', data => {
push.send([
this.channel
, wireutil.envelope(new wire.DeviceLogcatEntryMessage(options.serial, new Date().getTime() / 1000, DeviceLogger.stream.pid, DeviceLogger.stream.pid, 1, 'device:log:cat', data.toString()))
])
parser.write(data.toString())
let logs = parser.getObjects()
let threadId = 0
let processId = 0
let subsystem = '*'
let timestamp = new Date().getTime() / 1000
let message
logs.forEach(log => {
let logLevel = 2
switch (log.messageType) {
case 'Fatal': { logLevel = 7; break }
case 'Error': { logLevel = 6; break }
case 'Warning': { logLevel = 5; break }
case 'Default': { logLevel = 4; break }
case 'Activity': { logLevel = 3; break }
}

if (log.eventMessage) {
message = log.eventMessage
}
else if (log.formatString) {
message = log.formatString
}
else {
return
}

if (log.threadID) {
threadId = log.threadID
}

if (log.processID) {
processId = log.processID
}

if (log.timestamp) {
timestamp = log.timestamp
}

if (log.subsystem) {
subsystem = log.subsystem
}
else {
subsystem = '*'
}

push.send([
realGroup.group
, wireutil.envelope(new wire.DeviceLogcatEntryMessage(
options.serial
, Date.parse(timestamp) / 1000
, processId
, threadId
, logLevel
, subsystem
, message
))
])
})
})

DeviceLogger.stream.stderr.on('data', data => {
console.log(data.toString())
})

DeviceLogger.stream.on('close', err => {
log.fatal('Unable to get devicelog', err)
log.warn('Stream is closed', err)
DeviceLogger.killLoggingProcess()
})
}
Expand All @@ -52,7 +114,6 @@ export default syrup

, killLoggingProcess: () => {
if (DeviceLogger.stream) {
process.kill(-DeviceLogger.stream.pid)
DeviceLogger.stream.kill()
DeviceLogger.stream = null
DeviceLogger.channel = ''
Expand All @@ -76,7 +137,9 @@ export default syrup
}
})
.on(wire.LogcatStopMessage, function(channel, data) {
const reply = wireutil.reply(options.serial)
DeviceLogger.killLoggingProcess()
push.send([channel, reply.okay('success')])
})
.on(wire.GroupMessage, function(channel, data) {
DeviceLogger.channel = channel
Expand Down
133 changes: 133 additions & 0 deletions lib/units/ios-device/plugins/filesystem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import syrup from '@devicefarmer/stf-syrup'
import logger from '../../../util/logger.js'
import wire from '../../../wire/index.js'
import wireutil from '../../../wire/util.js'
import router from '../../base-device/support/router.js'
import push from '../../base-device/support/push.js'
import storage from '../../base-device/support/storage.js'
import {execFile} from 'child_process'
import path from 'path'
import fs from 'fs'
import {v4 as uuidv4} from 'uuid'
export default syrup.serial()
.dependency(router)
.dependency(push)
.dependency(storage)
.define(function(options, router, push, storage) {
const log = logger.createLogger('device:plugins:filesystem')
let plugin = Object.create(null)

const getIdbTarget = dir => {
let currentPath = dir.split('/')
let rootDir = currentPath[1]
if (['root', 'application', 'crashes'].indexOf(rootDir) !== -1) {
return rootDir
}
else {
return 'media'
}
}

router.on(wire.FileSystemGetMessage, function(channel, message) {
let reply = wireutil.reply(options.serial)
let file = message.file
log.info('Retrieving file "%s"', file)
let currentPath = file.split('/')
let target = getIdbTarget(file)
let tempFileName = `tmp_${uuidv4()}`

if (currentPath.length === 2) {
currentPath = ''
}
else {
currentPath = currentPath.slice(2).join('/').replace(' ', '\\ ')
}

execFile('idb', ['file', 'pull', `--${target}`, currentPath, `/tmp/${tempFileName}`, '--json', '--udid', options.serial],
(error, stdout, stderr) => {
if (error) {
log.warn('Unable to list directory "%s"', file, stderr)
}

storage.store('blob', path.basename(file), {
filename: path.basename(file)
, contentType: 'application/octet-stream'
}).then((file) => {
try {
push.send([
channel
, reply.okay('success', file)
])
}
catch (e) {
push.send([
channel
, reply.fail('error', e)
])
}
fs.unlink(`/tmp/${tempFileName}`, (err) => {
log.warn('Error while deleting file "%s"', file, err)
})
})
}
)
})
router.on(wire.FileSystemListMessage, function(channel, message) {
let reply = wireutil.reply(options.serial)
let dirs = []
let rootDir = message.dir
if (rootDir === '/') {
dirs = [
{name: 'root', mtime: '1970-01-01T00:00:00.000Z', atime: null, ctime: null, birthtime: null, mode: 16877, size: 0}
, {name: 'application', mtime: '1970-01-01T00:00:00.000Z', atime: null, ctime: null, birthtime: null, mode: 16877, size: 0}
, {name: 'crashes', mtime: '1970-01-01T00:00:00.000Z', atime: null, ctime: null, birthtime: null, mode: 16877, size: 0}
, {name: 'media', mtime: '1970-01-01T00:00:00.000Z', atime: null, ctime: null, birthtime: null, mode: 16877, size: 0}
]
push.send([
channel
, reply.okay('success', dirs)
])
}
let currentPath = message.dir.split('/')
let target = getIdbTarget(message.dir)

if (currentPath.length === 2) {
currentPath = ''
}
else {
currentPath = currentPath.slice(2).join('/').replace(' ', '\\ ')
}

execFile('idb', ['file', 'list', `--${target}`, currentPath, '--json', '--udid', options.serial],
(error, stdout, stderr) => {
if (error) {
log.warn('Unable to list directory "%s"', message.dir, stderr)
push.send([
channel
, reply.fail(error.message)
])
return
}

let rawDirs = JSON.parse(stdout)
let entries = []
rawDirs.forEach(dir => {
let name = dir.path
let mode = 0o40365
if (name.includes('.')) {
mode = 0o555
}
entries.push({
name: name, mtime: '1970-01-01T00:00:00.000Z', atime: null, ctime: null, birthtime: null, mode: mode, size: 0
})
})

push.send([
channel
, reply.okay('success', entries)
])
}
)
})
return plugin
})
6 changes: 2 additions & 4 deletions lib/units/ios-device/plugins/group.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default syrup.serial()
const baseUrl = iosutil.getUri(options.wdaHost, options.wdaPort)
let currentGroup = null
let plugin = new events.EventEmitter()
plugin.get = Promise.method(() => {
plugin.get = Promise.method(function() {
if (!currentGroup) {
throw new grouputil.NoGroupError()
}
Expand Down Expand Up @@ -193,9 +193,7 @@ export default syrup.serial()
.on(wire.GroupMessage, (channel, message) => {
let reply = wireutil.reply(options.serial)
// grouputil.match(ident, message.requirements)
Promise.method(() => {
return plugin.join(message.owner, message.timeout, message.usage)
})()
plugin.join(message.owner, message.timeout, message.usage)
.then(() => {
push.send([
channel
Expand Down
Loading

0 comments on commit 757572f

Please sign in to comment.