mirror of
https://github.com/appium/appium.git
synced 2026-01-28 05:09:10 -06:00
Return more appropriate info as server status and speed it up (#11232)
* Improve /status response for the umbrella driver
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import log from './logger';
|
||||
import { getAppiumConfig } from './config';
|
||||
import { getBuildInfo, updateBuildInfo } from './config';
|
||||
import { BaseDriver, errors, isSessionCommand } from 'appium-base-driver';
|
||||
import { FakeDriver } from 'appium-fake-driver';
|
||||
import { AndroidDriver } from 'appium-android-driver';
|
||||
@@ -148,6 +148,8 @@ class AppiumDriver extends BaseDriver {
|
||||
// it might be changed by other async calls at any time
|
||||
// It is not recommended to access this property directly from the outside
|
||||
this.pendingDrivers = {};
|
||||
|
||||
updateBuildInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,13 +203,9 @@ class AppiumDriver extends BaseDriver {
|
||||
}
|
||||
|
||||
async getStatus () {
|
||||
const config = await getAppiumConfig();
|
||||
const gitSha = config['git-sha'];
|
||||
const status = {build: {version: config.version}};
|
||||
if (!_.isEmpty(gitSha)) {
|
||||
status.build.revision = gitSha;
|
||||
}
|
||||
return status;
|
||||
return {
|
||||
build: _.clone(await getBuildInfo()),
|
||||
};
|
||||
}
|
||||
|
||||
async getSessions () {
|
||||
|
||||
129
lib/config.js
129
lib/config.js
@@ -1,11 +1,18 @@
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
import { mkdirp, fs } from 'appium-support';
|
||||
import { mkdirp, fs, system, util } from 'appium-support';
|
||||
import request from 'request-promise';
|
||||
import { exec } from 'teen_process';
|
||||
import { rootDir } from './utils';
|
||||
import logger from './logger';
|
||||
|
||||
const APPIUM_VER = require(path.resolve(rootDir, 'package.json')).version;
|
||||
const GIT_META_ROOT = '.git';
|
||||
const GIT_BINARY = `git${system.isWindows() ? '.exe' : ''}`;
|
||||
const GITHUB_API = 'https://api.github.com/repos/appium/appium';
|
||||
const BUILD_INFO = {
|
||||
version: APPIUM_VER,
|
||||
};
|
||||
|
||||
function getNodeVersion () {
|
||||
// expect v<major>.<minor>.<patch>
|
||||
@@ -14,24 +21,103 @@ function getNodeVersion () {
|
||||
return [Number(version[1]), Number(version[2])];
|
||||
}
|
||||
|
||||
async function getGitRev () {
|
||||
let rev = null;
|
||||
try {
|
||||
let {stdout} = await exec("git", ["rev-parse", "HEAD"], {rootDir});
|
||||
rev = stdout.trim();
|
||||
} catch (ign) {}
|
||||
return rev;
|
||||
async function updateBuildInfo () {
|
||||
const sha = await getGitRev(true);
|
||||
if (!sha) {
|
||||
return;
|
||||
}
|
||||
BUILD_INFO['git-sha'] = sha;
|
||||
const built = await getGitTimestamp(sha, true);
|
||||
if (!_.isEmpty(built)) {
|
||||
BUILD_INFO.built = built;
|
||||
}
|
||||
}
|
||||
|
||||
async function getAppiumConfig () {
|
||||
let stat = await fs.stat(path.resolve(__dirname, '..'));
|
||||
let built = stat.mtime.getTime();
|
||||
let config = {
|
||||
'git-sha': await getGitRev(),
|
||||
built,
|
||||
version: APPIUM_VER,
|
||||
};
|
||||
return config;
|
||||
async function getGitRev (useGitHubFallback = false) {
|
||||
if (await fs.exists(path.resolve(rootDir, GIT_META_ROOT))) {
|
||||
try {
|
||||
const {stdout} = await exec(GIT_BINARY, ['rev-parse', 'HEAD'], {
|
||||
cwd: rootDir
|
||||
});
|
||||
return stdout.trim();
|
||||
} catch (err) {
|
||||
logger.warn(`Cannot retrieve git revision for Appium version ${APPIUM_VER} from the local repository. ` +
|
||||
`Original error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!useGitHubFallback) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await request.get(`${GITHUB_API}/tags`, {
|
||||
headers: {
|
||||
'User-Agent': `Appium ${APPIUM_VER}`
|
||||
}
|
||||
});
|
||||
const resBodyObj = util.safeJsonParse(response);
|
||||
if (_.isArray(resBodyObj)) {
|
||||
for (const {name, commit} of resBodyObj) {
|
||||
if (name === `v${APPIUM_VER}` && commit && commit.sha) {
|
||||
return commit.sha;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn(`Cannot retrieve git revision for Appium version ${APPIUM_VER} from GitHub. ` +
|
||||
`Original error: ${err.message}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function getGitTimestamp (commitSha, useGitHubFallback = false) {
|
||||
if (await fs.exists(path.resolve(rootDir, GIT_META_ROOT))) {
|
||||
try {
|
||||
const {stdout} = await exec(GIT_BINARY, ['show', '-s', '--format=%ci', commitSha], {
|
||||
cwd: rootDir
|
||||
});
|
||||
return stdout.trim();
|
||||
} catch (err) {
|
||||
logger.warn(`Cannot retrieve the timestamp for Appium git commit ${commitSha} from the local repository. ` +
|
||||
`Original error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!useGitHubFallback) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await request.get(`${GITHUB_API}/commits/${commitSha}`, {
|
||||
headers: {
|
||||
'User-Agent': `Appium ${APPIUM_VER}`
|
||||
}
|
||||
});
|
||||
const resBodyObj = util.safeJsonParse(response);
|
||||
if (resBodyObj && resBodyObj.commit) {
|
||||
if (resBodyObj.commit.committer && resBodyObj.commit.committer.date) {
|
||||
return resBodyObj.commit.committer.date;
|
||||
}
|
||||
if (resBodyObj.commit.author && resBodyObj.commit.author.date) {
|
||||
return resBodyObj.commit.author.date;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn(`Cannot retrieve the timestamp for Appium git commit ${commitSha} from GitHub. ` +
|
||||
`Original error: ${err.message}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns Mutable object containing Appium build information. By default it
|
||||
* only contains the Appium version, but is updated with the build timestamp
|
||||
* and git commit hash asynchronously as soon as `updateBuildInfo` is called
|
||||
* and succeeds.
|
||||
*/
|
||||
async function getBuildInfo () {
|
||||
return BUILD_INFO;
|
||||
}
|
||||
|
||||
function checkNodeOk () {
|
||||
@@ -52,8 +138,8 @@ function warnNodeDeprecations () {
|
||||
}
|
||||
|
||||
async function showConfig () {
|
||||
let config = await getAppiumConfig();
|
||||
console.log(JSON.stringify(config)); // eslint-disable-line no-console
|
||||
await updateBuildInfo();
|
||||
console.log(JSON.stringify(await getBuildInfo())); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
function getNonDefaultArgs (parser, args) {
|
||||
@@ -142,6 +228,7 @@ async function validateTmpDir (tmpDir) {
|
||||
}
|
||||
}
|
||||
|
||||
export { getAppiumConfig, validateServerArgs, checkNodeOk, showConfig,
|
||||
export { getBuildInfo, validateServerArgs, checkNodeOk, showConfig,
|
||||
warnNodeDeprecations, validateTmpDir, getNonDefaultArgs,
|
||||
getDeprecatedArgs, getGitRev, checkValidPort, APPIUM_VER };
|
||||
getDeprecatedArgs, getGitRev, checkValidPort, APPIUM_VER,
|
||||
updateBuildInfo };
|
||||
|
||||
@@ -4,12 +4,14 @@ import _ from 'lodash';
|
||||
import chai from 'chai';
|
||||
import sinon from 'sinon';
|
||||
import chaiAsPromised from 'chai-as-promised';
|
||||
import { getGitRev, getAppiumConfig, checkNodeOk, warnNodeDeprecations,
|
||||
import { getGitRev, getBuildInfo, checkNodeOk, warnNodeDeprecations,
|
||||
getNonDefaultArgs, getDeprecatedArgs, validateServerArgs,
|
||||
validateTmpDir, showConfig, checkValidPort } from '../lib/config';
|
||||
validateTmpDir, showConfig, checkValidPort, updateBuildInfo,
|
||||
APPIUM_VER } from '../lib/config';
|
||||
import getParser from '../lib/parser';
|
||||
import logger from '../lib/logger';
|
||||
|
||||
import { fs } from 'appium-support';
|
||||
import request from 'request-promise';
|
||||
|
||||
let should = chai.should();
|
||||
chai.use(chaiAsPromised);
|
||||
@@ -26,13 +28,89 @@ describe('Config', function () {
|
||||
});
|
||||
|
||||
describe('Appium config', function () {
|
||||
describe('getAppiumConfig', function () {
|
||||
it('should get a configuration object', async function () {
|
||||
let config = await getAppiumConfig();
|
||||
config.should.be.an('object');
|
||||
should.exist(config['git-sha']);
|
||||
should.exist(config.built);
|
||||
should.exist(config.version);
|
||||
describe('getBuildInfo', function () {
|
||||
async function verifyBuildInfoUpdate (useLocalGit) {
|
||||
const buildInfo = await getBuildInfo();
|
||||
mockFs.expects('exists').atLeast(1).returns(useLocalGit);
|
||||
buildInfo['git-sha'] = undefined;
|
||||
buildInfo.built = undefined;
|
||||
await updateBuildInfo();
|
||||
buildInfo.should.be.an('object');
|
||||
should.exist(buildInfo['git-sha']);
|
||||
should.exist(buildInfo.built);
|
||||
should.exist(buildInfo.version);
|
||||
}
|
||||
|
||||
let mockFs;
|
||||
let getStub;
|
||||
beforeEach(function () {
|
||||
mockFs = sinon.mock(fs);
|
||||
getStub = sinon.stub(request, 'get');
|
||||
});
|
||||
afterEach(function () {
|
||||
getStub.restore();
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should get a configuration object if the local git metadata is present', async function () {
|
||||
await verifyBuildInfoUpdate(true);
|
||||
});
|
||||
it('should get a configuration object if the local git metadata is not present', async function () {
|
||||
getStub.onCall(0).returns([
|
||||
{
|
||||
"name": `v${APPIUM_VER}`,
|
||||
"zipball_url": "https://api.github.com/repos/appium/appium/zipball/v1.9.0-beta.1",
|
||||
"tarball_url": "https://api.github.com/repos/appium/appium/tarball/v1.9.0-beta.1",
|
||||
"commit": {
|
||||
"sha": "3c2752f9f9c56000705a4ae15b3ba68a5d2e644c",
|
||||
"url": "https://api.github.com/repos/appium/appium/commits/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c"
|
||||
},
|
||||
"node_id": "MDM6UmVmNzUzMDU3MDp2MS45LjAtYmV0YS4x"
|
||||
},
|
||||
{
|
||||
"name": "v1.8.2-beta",
|
||||
"zipball_url": "https://api.github.com/repos/appium/appium/zipball/v1.8.2-beta",
|
||||
"tarball_url": "https://api.github.com/repos/appium/appium/tarball/v1.8.2-beta",
|
||||
"commit": {
|
||||
"sha": "5b98b9197e75aa85e7507d21d3126c1a63d1ce8f",
|
||||
"url": "https://api.github.com/repos/appium/appium/commits/5b98b9197e75aa85e7507d21d3126c1a63d1ce8f"
|
||||
},
|
||||
"node_id": "MDM6UmVmNzUzMDU3MDp2MS44LjItYmV0YQ=="
|
||||
}
|
||||
]);
|
||||
getStub.onCall(1).returns({
|
||||
"sha": "3c2752f9f9c56000705a4ae15b3ba68a5d2e644c",
|
||||
"node_id": "MDY6Q29tbWl0NzUzMDU3MDozYzI3NTJmOWY5YzU2MDAwNzA1YTRhZTE1YjNiYTY4YTVkMmU2NDRj",
|
||||
"commit": {
|
||||
"author": {
|
||||
"name": "Isaac Murchie",
|
||||
"email": "isaac@saucelabs.com",
|
||||
"date": "2018-08-17T19:48:00Z"
|
||||
},
|
||||
"committer": {
|
||||
"name": "Isaac Murchie",
|
||||
"email": "isaac@saucelabs.com",
|
||||
"date": "2018-08-17T19:48:00Z"
|
||||
},
|
||||
"message": "v1.9.0-beta.1",
|
||||
"tree": {
|
||||
"sha": "2c0974727470eba419ea0b9951c52f72f8036b18",
|
||||
"url": "https://api.github.com/repos/appium/appium/git/trees/2c0974727470eba419ea0b9951c52f72f8036b18"
|
||||
},
|
||||
"url": "https://api.github.com/repos/appium/appium/git/commits/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c",
|
||||
"comment_count": 0,
|
||||
"verification": {
|
||||
"verified": false,
|
||||
"reason": "unsigned",
|
||||
"signature": null,
|
||||
"payload": null
|
||||
}
|
||||
},
|
||||
"url": "https://api.github.com/repos/appium/appium/commits/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c",
|
||||
"html_url": "https://github.com/appium/appium/commit/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c",
|
||||
"comments_url": "https://api.github.com/repos/appium/appium/commits/3c2752f9f9c56000705a4ae15b3ba68a5d2e644c/comments",
|
||||
});
|
||||
await verifyBuildInfoUpdate(false);
|
||||
});
|
||||
});
|
||||
describe('showConfig', function () {
|
||||
@@ -40,7 +118,7 @@ describe('Config', function () {
|
||||
sinon.spy(console, "log");
|
||||
});
|
||||
it('should log the config to console', async function () {
|
||||
let config = await getAppiumConfig();
|
||||
const config = await getBuildInfo();
|
||||
await showConfig();
|
||||
console.log.calledOnce.should.be.true; // eslint-disable-line no-console
|
||||
console.log.getCall(0).args[0].should.contain(JSON.stringify(config)); // eslint-disable-line no-console
|
||||
|
||||
Reference in New Issue
Block a user