Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tizen devices fixes #1703

Merged
merged 10 commits into from
Sep 20, 2024
66 changes: 54 additions & 12 deletions packages/sdk-tizen/src/__tests__/deviceManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
inquirerPrompt,
ExecOptionsPresets,
} from '@rnv/core';
import { listTizenTargets, launchTizenEmulator } from '../deviceManager';
import { listTizenTargets, launchTizenTarget } from '../deviceManager';
import { CLI_TIZEN_EMULATOR, CLI_SDB_TIZEN } from '../constants';

const ERROR_MSG = {
Expand Down Expand Up @@ -84,17 +84,17 @@ describe('listTizenTargets', () => {
});
});

describe('launchTizenEmulator', () => {
describe('launchTizenTarget', () => {
it('should launch the specified emulator by name', async () => {
const mockContext = { cli: { [CLI_TIZEN_EMULATOR]: 'tizen-emulator' }, platform: 'tizen' };
const ctx = { ...getContext(), ...mockContext };
createRnvContext(ctx);

(executeAsync as jest.Mock).mockResolvedValue(true);

const result = await launchTizenEmulator('emulatorName');
const result = await launchTizenTarget('emulatorName');

expect(logDefault).toHaveBeenCalledWith('launchTizenEmulator:emulatorName');
expect(logDefault).toHaveBeenCalledWith('launchTizenTarget:emulatorName');
expect(executeAsync).toHaveBeenCalledWith(
'tizen-emulator launch --name emulatorName',
ExecOptionsPresets.SPINNER_FULL_ERROR_SUMMARY
Expand All @@ -109,13 +109,13 @@ describe('launchTizenEmulator', () => {
(execCLI as jest.Mock).mockResolvedValueOnce('emulator1\nemulator2').mockResolvedValueOnce('device1\ndevice2');
(inquirerPrompt as jest.Mock).mockResolvedValue({ chosenEmulator: 'emulator1' });
(executeAsync as jest.Mock).mockResolvedValue(true);
const result = await launchTizenEmulator(true);
const result = await launchTizenTarget(true);
expect(execCLI).toHaveBeenCalledWith(CLI_TIZEN_EMULATOR, 'list-vm');
expect(execCLI).toHaveBeenCalledWith(CLI_SDB_TIZEN, 'devices');
expect(inquirerPrompt).toHaveBeenCalledWith({
name: 'chosenEmulator',
type: 'list',
message: 'What emulator would you like to launch?',
message: 'which emulator or device would you like to launch?',
choices: expect.any(Array),
});
expect(executeAsync).toHaveBeenCalledWith(
Expand All @@ -124,6 +124,48 @@ describe('launchTizenEmulator', () => {
);
expect(result).toBe(true);
});
it('should hide real devices from prompt, if true is passed', async () => {
const mockContext = { cli: { [CLI_TIZEN_EMULATOR]: 'tizen-emulator' }, platform: 'tizen' };
const ctx = { ...getContext(), ...mockContext };
createRnvContext(ctx);

(execCLI as jest.Mock)
.mockResolvedValueOnce('emulator1\nemulator2')
.mockResolvedValueOnce(
'firstTrashLineThatTizenDeviceCmdReturns\n111.111.0.111:26101 device UE43NU7192'
);
(inquirerPrompt as jest.Mock).mockResolvedValue({ chosenEmulator: 'emulator1' });
(executeAsync as jest.Mock).mockResolvedValue(true);
const result = await launchTizenTarget(true, true);
expect(inquirerPrompt).toHaveBeenCalledWith({
name: 'chosenEmulator',
type: 'list',
message: 'which emulator or device would you like to launch?',
choices: [], // not correct, because emulators are not mocked, but doesn't matter here, since its testing devices
});
expect(result).toBe(true);
});
it('should show real devices(same conditions as test above, just not passing 2nd param true to launchTizenTarget) ', async () => {
const mockContext = { cli: { [CLI_TIZEN_EMULATOR]: 'tizen-emulator' }, platform: 'tizen' };
const ctx = { ...getContext(), ...mockContext };
createRnvContext(ctx);

(execCLI as jest.Mock)
.mockResolvedValueOnce('emulator1\nemulator2')
.mockResolvedValueOnce(
'firstTrashLineThatTizenDeviceCmdReturns\n111.111.0.111:26101 device UE43NU7192'
);
(inquirerPrompt as jest.Mock).mockResolvedValue({ chosenEmulator: 'emulator1' });
(executeAsync as jest.Mock).mockResolvedValue(true);
const result = await launchTizenTarget(true);
expect(inquirerPrompt).toHaveBeenCalledWith({
name: 'chosenEmulator',
type: 'list',
message: 'which emulator or device would you like to launch?',
choices: [{ key: '111.111.0.111:26101', name: '111.111.0.111:26101', value: '111.111.0.111:26101' }],
});
expect(result).toBe(true);
});
it('should handle unknown VM error and retry with prompt', async () => {
const mockContext = { cli: { [CLI_TIZEN_EMULATOR]: 'tizen-emulator' }, platform: 'tizen' };
const ctx = { ...getContext(), ...mockContext };
Expand All @@ -133,14 +175,14 @@ describe('launchTizenEmulator', () => {
(execCLI as jest.Mock).mockResolvedValueOnce('emulator1\nemulator2').mockResolvedValueOnce('device1\ndevice2');
(inquirerPrompt as jest.Mock).mockResolvedValue({ chosenEmulator: 'emulator1' });
(executeAsync as jest.Mock).mockResolvedValue(true);
const result = await launchTizenEmulator('unknownEmulator');
expect(logError).toHaveBeenCalledWith('The VM "unknownEmulator" does not exist.');
const result = await launchTizenTarget('unknownEmulator');
expect(logError).toHaveBeenCalledWith('The VM/device "unknownEmulator" does not exist.');
expect(execCLI).toHaveBeenCalledWith(CLI_TIZEN_EMULATOR, 'list-vm');
expect(execCLI).toHaveBeenCalledWith(CLI_SDB_TIZEN, 'devices');
expect(inquirerPrompt).toHaveBeenCalledWith({
name: 'chosenEmulator',
type: 'list',
message: 'What emulator would you like to launch?',
message: 'which emulator or device would you like to launch?',
choices: expect.any(Array),
});
expect(executeAsync).toHaveBeenCalledWith(
Expand All @@ -155,11 +197,11 @@ describe('launchTizenEmulator', () => {
createRnvContext(ctx);

(executeAsync as jest.Mock).mockRejectedValueOnce(ERROR_MSG.ALREADY_RUNNING);
const result = await launchTizenEmulator('runningEmulator');
expect(logError).toHaveBeenCalledWith('The VM "runningEmulator" is already running.');
const result = await launchTizenTarget('runningEmulator');
expect(logError).toHaveBeenCalledWith('The VM/device "runningEmulator" is already running.');
expect(result).toBe(true);
});
it('should reject if no name is specified', async () => {
await expect(launchTizenEmulator('')).rejects.toEqual('No emulator -t target name specified!');
await expect(launchTizenTarget('')).rejects.toEqual('No emulator -t target name specified!');
});
});
46 changes: 26 additions & 20 deletions packages/sdk-tizen/src/deviceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
const ERROR_MSG = {
UNKNOWN_VM: 'does not match any VM',
ALREADY_RUNNING: 'is running now',
NO_SUPPORT: 'Your system cannot support HW virtualization',
};

type PlatKeyObj = {
Expand Down Expand Up @@ -71,60 +72,62 @@
return {};
};

export const launchTizenEmulator = async (name: string | true): Promise<boolean> => {
export const launchTizenTarget = async (name: string | true, hideDevices?: boolean): Promise<boolean> => {
const c = getContext();
logDefault(`launchTizenEmulator:${name}`);

logDefault(`launchTizenTarget:${name}`);
if (name === true) {
const emulators = await execCLI(CLI_TIZEN_EMULATOR, 'list-vm');
const devices = await execCLI(CLI_SDB_TIZEN, 'devices');
const devices_lines = devices.split('\n');

const allDownloadedEmulators = emulators.split('\n'); // all tizen, tizenwatch and tizenmobile emulators

const specificEmulators = await getSubplatformDevices(allDownloadedEmulators, c.platform as string);
const devicesArr = devices_lines.slice(1).map((line: string) => line.split(' ')[0]); // devices array with only their ip

const lines = specificEmulators.concat(devicesArr);

const targetsArray = lines.map((line) => ({ id: line, name: line }));
const targetsArray = hideDevices
? specificEmulators.map((line) => ({ id: line, name: line }))
: lines.map((line) => ({ id: line, name: line }));

const choices = _composeDevicesString(targetsArray);

const { chosenEmulator } = await inquirerPrompt({
name: 'chosenEmulator',
type: 'list',
message: 'What emulator would you like to launch?',
message: 'which emulator or device would you like to launch?',
choices,
});

name = chosenEmulator;
}

if (name) {
if (name && typeof name === 'string') {
const ipRegex = /^(?:\d{1,3}\.){3}\d{1,3}:\d{1,5}$/;
if (name !== true && ipRegex.test(name)) {
if (ipRegex.test(name)) {
// if ip is chosen, real device boot should start
logInfo('Connecting to device');
c.runtime.target = name.split(':')[0];
await runTizenSimOrDevice();
return true;
return new Promise(() => logInfo('Device is launched.'));
}
try {
await executeAsync(
`${c.cli[CLI_TIZEN_EMULATOR]} launch --name ${name}`,

Check warning

Code scanning / CodeQL

Unsafe shell command constructed from library input Medium

This string concatenation which depends on
library input
is later used in a
shell command
.
ExecOptionsPresets.SPINNER_FULL_ERROR_SUMMARY
);
return true;
} catch (e) {
if (typeof e === 'string') {
if (e.includes(ERROR_MSG.UNKNOWN_VM)) {
logError(`The VM "${name}" does not exist.`);
return launchTizenEmulator(true);
logError(`The VM/device "${name}" does not exist.`);
return launchTizenTarget(true, hideDevices);
}

if (e.includes(ERROR_MSG.ALREADY_RUNNING)) {
logError(`The VM "${name}" is already running.`);
logError(`The VM/device "${name}" is already running.`);
return true;
}
if (e.includes(ERROR_MSG.NO_SUPPORT)) {
logError(`Your system cannot support HW virtualization.`);
return true;
}
}
Expand Down Expand Up @@ -384,8 +387,11 @@
let deviceID: string;

if (!tId) return Promise.reject(`Tizen platform requires "id" filed in platforms.tizen`);

const askForEmulator = async () => {
if (!target) {
launchTizenTarget(true);
return;
}
const { startEmulator } = await inquirerPrompt({
name: 'startEmulator',
type: 'confirm',
Expand All @@ -400,15 +406,15 @@
return;
}
try {
await launchTizenEmulator(defaultTarget);
await launchTizenTarget(defaultTarget);
deviceID = defaultTarget;
await _waitForEmulatorToBeReady(defaultTarget);
return continueLaunching();
} catch (e) {
logDebug(`askForEmulator:ERRROR: ${e}`);
try {
await execCLI(CLI_TIZEN_EMULATOR, `create -n ${defaultTarget} -p tv-samsung-5.0-x86`);
await launchTizenEmulator(defaultTarget);
await launchTizenTarget(defaultTarget);
deviceID = defaultTarget;
await _waitForEmulatorToBeReady(defaultTarget);
return continueLaunching();
Expand Down Expand Up @@ -439,7 +445,7 @@
if (typeof e === 'string' && e.includes('No device matching')) {
if (target) {
isRunningEmulator = true;
await launchTizenEmulator(target);
await launchTizenTarget(target);
hasDevice = await _waitForEmulatorToBeReady(target);
} else {
return Promise.reject('Not target specified. (-t)');
Expand Down Expand Up @@ -469,7 +475,7 @@

if (target) {
isRunningEmulator = true;
await launchTizenEmulator(target);
await launchTizenTarget(target);
hasDevice = await _waitForEmulatorToBeReady(target);
} else {
return Promise.reject('Not target specified. (-t)');
Expand Down Expand Up @@ -516,7 +522,7 @@
try {
// try to launch it, see if it's a emulator that's not started yet
isRunningEmulator = true;
await launchTizenEmulator(target);
await launchTizenTarget(target);
await _waitForEmulatorToBeReady(target);
deviceID = target;
return continueLaunching();
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk-tizen/src/tasks/taskTargetLaunch.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createTask, RnvTaskName, RnvTaskOptions } from '@rnv/core';
import { getTargetWithOptionalPrompt } from '@rnv/sdk-utils';
import { checkAndConfigureTizenSdks, checkTizenSdk } from '../installer';
import { launchTizenEmulator } from '../deviceManager';
import { launchTizenTarget } from '../deviceManager';
import { SdkPlatforms } from '../constants';

export default createTask({
Expand All @@ -11,7 +11,7 @@ export default createTask({
await checkAndConfigureTizenSdks();
const target = await getTargetWithOptionalPrompt();
await checkTizenSdk();
return launchTizenEmulator(target);
return launchTizenTarget(target, true);
},
task: RnvTaskName.targetLaunch,
options: [RnvTaskOptions.target],
Expand Down
Loading