Skip to content

Commit 5ffe083

Browse files
committed
Fixed all tests for macOS
1 parent d66afed commit 5ffe083

17 files changed

Lines changed: 116 additions & 108 deletions

File tree

.cirrus.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@ integration_test_dev_macos_task:
1616
timeout_in: 120m
1717
macos_instance:
1818
image: codify-test-vm
19+
cpu: 4
20+
memory: 6124
21+
storage: 100
1922
node_modules_cache:
2023
folder: node_modules
2124
fingerprint_script: cat package-lock.json
2225
populate_script: npm ci
2326
test_script:
24-
- npm run test:integration -- --disable-console-intercept $DEBUG --no-file-parallelism
27+
- zsh -i -c "npm run test:integration -- --disable-console-intercept $DEBUG --no-file-parallelism"
2528

2629
integration_test_dev_linux_task:
2730
# trick cirrus CI to use tart here to run a linux instance
@@ -46,7 +49,7 @@ integration_individual_test_macos_task:
4649
populate_script: npm ci
4750
test_script:
4851
- echo $FILE_NAME
49-
- npm run test -- $FILE_NAME --disable-console-intercept $DEBUG --no-file-parallelism
52+
- zsh -i -c "npm run test -- $FILE_NAME --disable-console-intercept $DEBUG --no-file-parallelism"
5053

5154
integration_individual_test_linux_task:
5255
arm_container:

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"ajv": "^8.12.0",
2727
"ajv-formats": "^2.1.1",
2828
"chalk": "^5.3.0",
29-
"codify-plugin-lib": "1.0.182-beta55",
29+
"codify-plugin-lib": "1.0.182-beta57",
3030
"codify-schemas": "1.0.86-beta7",
3131
"debug": "^4.3.4",
3232
"lodash.isequal": "^4.5.0",
@@ -55,7 +55,7 @@
5555
"@types/node": "^18",
5656
"@types/plist": "^3.0.5",
5757
"@types/semver": "^7.5.4",
58-
"codify-plugin-test": "0.0.53-beta17",
58+
"codify-plugin-test": "0.0.53-beta23",
5959
"commander": "^12.1.0",
6060
"eslint": "^8.51.0",
6161
"eslint-config-oclif": "^5",

scripts/init.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
tart clone ghcr.io/cirruslabs/macos-tahoe-base:latest codify-test-vm
2-
tart set codify-test-vm --memory 6124 --cpu 4 --storage 64
2+
tart set codify-test-vm --memory 6124 --cpu 4 --storage 128
33

44
# tart clone ghcr.io/kevinwang5658/sonoma-codify:v0.0.3 codify-sonoma

scripts/run-tests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ async function launchPersistentTest(test: string, debug: boolean, operatingSyste
9696

9797
console.log('Done refreshing files on VM. Starting tests...');
9898
VerbosityLevel.set(3);
99-
await codifySpawn(`tart exec ${vmName} ${shell} -c "cd ${dir} && FORCE_COLOR=true npm run test -- ${test} --disable-console-intercept ${debugFlag} --no-file-parallelism"`, { throws: false });
99+
await codifySpawn(`tart exec ${vmName} ${shell} -c ${operatingSystem === 'darwin' ? '-i' : ''} "cd ${dir} && FORCE_COLOR=true npm run test -- ${test} --disable-console-intercept ${debugFlag} --no-file-parallelism"`, { throws: false });
100100
// }
101101
}
102102

src/resources/docker/docker.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ export class DockerResource extends Resource<DockerConfig> {
8282
await $.spawn(`/Volumes/Docker/Docker.app/Contents/MacOS/install ${plan.desiredConfig.acceptLicense ? '--accept-license' : ''} ${plan.desiredConfig.useCurrentUser ? `--user ${user}` : ''}`,
8383
{ requiresRoot: true }
8484
)
85+
86+
// TODO: Attempt to sleep until Docker is ready
87+
await this.sleep(1000);
8588
await $.spawn('hdiutil detach /Volumes/Docker', { cwd: tmpDir })
8689
} finally {
8790
await fs.rm(tmpDir, { recursive: true, force: true })
@@ -102,4 +105,8 @@ export class DockerResource extends Resource<DockerConfig> {
102105
await FileUtils.removeLineFromStartupFile('/Applications/Docker.app/Contents/Resources/bin')
103106
}
104107

108+
async sleep(ms: number): Promise<void> {
109+
return new Promise(resolve => setTimeout(resolve, ms));
110+
}
111+
105112
}

src/resources/git/lfs/git-lfs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export class GitLfsResource extends Resource<GitLfsConfig> {
5858
private async checkIfGitLfsIsInstalled(): Promise<boolean> {
5959
const $ = getPty();
6060

61-
const gitLfsStatus = await $.spawn('git lfs env', { cwd: os.homedir(), interactive: true });
61+
const gitLfsStatus = await $.spawn('git lfs env', { cwd: os.homedir(), interactive: true, disableWrapping: true });
6262
const lines = gitLfsStatus.data.split('\n');
6363

6464
// When git lfs exists but git lfs install hasn't been called then git lfs env returns:

src/resources/python/pyenv/python-versions-parameter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ export class PythonVersionsParameter extends ArrayStatefulParameter<PyenvConfig,
3535

3636
override async addItem(version: string): Promise<void> {
3737
const $ = getPty();
38-
await $.spawn(`pyenv install ${version}`, { interactive: true });
38+
await $.spawn(`pyenv install ${version} -s`, { interactive: true });
3939
}
4040

4141
override async removeItem(version: string): Promise<void> {
4242
const $ = getPty();
43-
await $.spawn(`pyenv uninstall ${version}`, { interactive: true });
43+
await $.spawn(`pyenv uninstall ${version} -f`, { interactive: true });
4444
}
4545
}

src/resources/tart/tart-vm.ts

Lines changed: 69 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import { CreatePlan, DestroyPlan, Resource, ResourceSettings, SpawnStatus, getPty, z } from 'codify-plugin-lib';
1+
import {
2+
CreatePlan,
3+
DestroyPlan,
4+
Resource,
5+
ResourceSettings,
6+
SpawnStatus,
7+
getPty,
8+
z,
9+
ParameterChange, ModifyPlan
10+
} from 'codify-plugin-lib';
211
import { OS } from 'codify-schemas';
312

413
const schema = z.object({
@@ -20,10 +29,6 @@ const schema = z.object({
2029
.string()
2130
.describe('Sets the display size in format <width>x<height>. For example 1200x800')
2231
.optional(),
23-
disk: z
24-
.string()
25-
.describe('The location of the disk, which is a path')
26-
.optional(),
2732
diskSize: z
2833
.number()
2934
.describe('The disk size in GB. Disk size can only be increased and not decreased')
@@ -40,7 +45,10 @@ export class TartVmResource extends Resource<TartVmConfig> {
4045
dependencies: ['tart'],
4146
schema,
4247
parameterSettings: {
43-
disk: { type: 'directory' },
48+
diskSize: { type: 'number', canModify: true },
49+
memory: { type: 'number', canModify: true },
50+
cpu: { type: 'number', canModify: true },
51+
display: { type: 'string', canModify: true },
4452
},
4553
};
4654
}
@@ -64,10 +72,18 @@ export class TartVmResource extends Resource<TartVmConfig> {
6472
// Parse the JSON output to get the list of VMs
6573
try {
6674
const vmList = JSON.parse(data);
75+
console.log('VM list:', vmList);
76+
console.log('Local name:', parameters.localName);
77+
console.log('Includes VM:', vmList.some((vm: { Name: string }) => vm.Name === parameters.localName));
78+
6779
if (!vmList.some((vm: { Name: string }) => vm.Name === parameters.localName)) {
80+
console.log('Not found! returning null')
81+
6882
return null;
6983
}
70-
} catch {
84+
} catch(e) {
85+
console.error('Error parsing JSON:', e);
86+
7187
// If JSON parsing fails, return null
7288
return null;
7389
}
@@ -77,40 +93,24 @@ export class TartVmResource extends Resource<TartVmConfig> {
7793
sourceName: parameters.sourceName,
7894
}
7995

80-
// Get VM configuration using tart get
81-
const { status: getStatus, data: getData } = await $.spawnSafe(`tart get ${parameters.localName}`);
82-
if (getStatus === SpawnStatus.SUCCESS) {
83-
// Parse the output to extract configuration
84-
const lines = getData.split('\n');
85-
86-
for (const line of lines) {
87-
if (line.includes('memory:')) {
88-
const match = line.match(/memory:\s*(\d+)/);
89-
if (match) {
90-
result.memory = Number.parseInt(match[1], 10);
91-
}
92-
} else if (line.includes('cpu:')) {
93-
const match = line.match(/cpu:\s*(\d+)/);
94-
if (match) {
95-
result.cpu = Number.parseInt(match[1], 10);
96-
}
97-
} else if (line.includes('display:')) {
98-
const match = line.match(/display:\s*(\d+x\d+)/);
99-
if (match) {
100-
result.display = match[1];
101-
}
102-
} else if (line.includes('disk:')) {
103-
const match = line.match(/disk:\s*(.+)/);
104-
if (match) {
105-
result.disk = match[1].trim();
106-
}
107-
} else if (line.includes('disk-size:')) {
108-
const match = line.match(/disk-size:\s*(\d+)/);
109-
if (match) {
110-
result.diskSize = Number.parseInt(match[1], 10);
111-
}
112-
}
96+
try {
97+
// Get VM configuration using tart get
98+
const { status: getStatus, data: getData } = await $.spawnSafe(`tart get ${parameters.localName} --format json`);
99+
console.log('Get data:', getData);
100+
console.log('Status:', getStatus);
101+
102+
if (getStatus === SpawnStatus.SUCCESS) {
103+
// Parse the output to extract configuration
104+
105+
const vmInfo = JSON.parse(getData);
106+
result.memory = vmInfo.Memory;
107+
result.cpu = vmInfo.CPU;
108+
result.display = vmInfo.Display;
109+
result.diskSize = vmInfo.Disk;
113110
}
111+
} catch {
112+
// If JSON parsing fails, return null
113+
return result;
114114
}
115115

116116
return result;
@@ -120,7 +120,7 @@ export class TartVmResource extends Resource<TartVmConfig> {
120120
const $ = getPty();
121121

122122
// Determine the VM name
123-
const vmName = plan.desiredConfig.localName || this.extractNameFromSource(plan.desiredConfig.sourceName);
123+
const vmName = plan.desiredConfig.localName;
124124

125125
if (!vmName) {
126126
throw new Error('Unable to determine VM name. Please provide either "name" or a valid "sourceName"');
@@ -144,42 +144,53 @@ export class TartVmResource extends Resource<TartVmConfig> {
144144
setCommands.push(`--display ${plan.desiredConfig.display}`);
145145
}
146146

147-
if (plan.desiredConfig.disk) {
148-
setCommands.push(`--disk ${plan.desiredConfig.disk}`);
147+
if (plan.desiredConfig.diskSize) {
148+
setCommands.push(`--disk-size ${plan.desiredConfig.diskSize}`);
149+
}
150+
151+
if (setCommands.length > 0) {
152+
await $.spawn(`tart set ${vmName} ${setCommands.join(' ')}`, { interactive: true });
153+
}
154+
}
155+
156+
async modify(pc: ParameterChange<TartVmConfig>, plan: ModifyPlan<TartVmConfig>): Promise<void> {
157+
const $ = getPty();
158+
159+
// Set VM parameters if specified
160+
const setCommands: string[] = [];
161+
162+
if (plan.desiredConfig.memory) {
163+
setCommands.push(`--memory ${plan.desiredConfig.memory}`);
164+
}
165+
166+
if (plan.desiredConfig.cpu) {
167+
setCommands.push(`--cpu ${plan.desiredConfig.cpu}`);
168+
}
169+
170+
if (plan.desiredConfig.display) {
171+
setCommands.push(`--display ${plan.desiredConfig.display}`);
149172
}
150173

151174
if (plan.desiredConfig.diskSize) {
152175
setCommands.push(`--disk-size ${plan.desiredConfig.diskSize}`);
153176
}
154177

155178
if (setCommands.length > 0) {
156-
await $.spawn(`tart set ${vmName} ${setCommands.join(' ')}`, { interactive: true });
179+
await $.spawn(`tart set ${plan.desiredConfig.localName} ${setCommands.join(' ')}`, { interactive: true });
157180
}
158181
}
159182

160183
async destroy(plan: DestroyPlan<TartVmConfig>): Promise<void> {
161184
const $ = getPty();
162185

163186
// Determine the VM name
164-
const vmName = plan.currentConfig.localName || this.extractNameFromSource(plan.currentConfig.sourceName);
187+
const vmName = plan.currentConfig.localName;
165188

166189
if (!vmName) {
167190
throw new Error('Unable to determine VM name');
168191
}
169192

170193
// Delete the VM
171-
await $.spawn(`tart delete ${vmName}`, { interactive: true });
172-
}
173-
174-
private extractNameFromSource(sourceName: string): string {
175-
// Extract the name from the source
176-
// For example: ghcr.io/user/image:tag -> image:tag or just image
177-
const parts = sourceName.split('/');
178-
const lastPart = parts.at(-1)!;
179-
180-
// Remove the tag if present
181-
const nameWithoutTag = lastPart.split(':')[0];
182-
183-
return nameWithoutTag;
194+
await $.spawnSafe(`tart delete ${vmName}`, { interactive: true });
184195
}
185196
}

test/asdf/asdf.test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ import os from 'node:os';
99
describe('Asdf tests', async () => {
1010
const pluginPath = path.resolve('./src/index.ts');
1111

12-
beforeAll(async () => {
13-
await TestUtils.ensureHomebrewInstalled(pluginPath);
14-
}, 300000)
15-
1612
it('Can install asdf and plugins', { timeout: 300000 }, async () => {
1713
await PluginTester.fullTest(pluginPath, [
1814
{

0 commit comments

Comments
 (0)