-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathtest-roundtrip.js
More file actions
153 lines (122 loc) Β· 4.78 KB
/
test-roundtrip.js
File metadata and controls
153 lines (122 loc) Β· 4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env node
import http from 'http';
import fs from 'fs';
const BASE_URL = 'http://localhost:5000';
function makeRequest(path, method = 'GET', data = null) {
return new Promise((resolve, reject) => {
const url = new URL(path, BASE_URL);
const options = {
hostname: url.hostname,
port: url.port,
path: url.pathname,
method: method,
headers: {
'Content-Type': 'application/json',
}
};
const req = http.request(options, (res) => {
let body = '';
res.on('data', (chunk) => body += chunk);
res.on('end', () => {
try {
resolve(JSON.parse(body));
} catch (e) {
resolve(body);
}
});
});
req.on('error', reject);
if (data) {
req.write(JSON.stringify(data));
}
req.end();
});
}
async function runRoundTripTest() {
console.log('π§ͺ Starting Round-Trip Parity Test...\n');
// Step 1: Get baseline configuration
console.log('π₯ Fetching baseline configuration...');
const baseline = await makeRequest('/api/configuration/default');
console.log('β
Baseline fetched\n');
// Step 2: Generate package (which includes all export formats)
console.log('π¦ Generating export package...');
const packageData = await makeRequest('/api/package/generate', 'POST', {
configuration: baseline,
includeFiles: ["env", "yaml"]
});
console.log('β
Package generated\n');
// Step 3: Parse the exports from the package
const yamlContent = packageData.files['librechat.yaml'];
const envContent = packageData.files['.env'];
const jsonContent = packageData.files['LibreChatConfigSettings.json'];
const jsonExport = JSON.parse(jsonContent);
// Step 4: Test each format
const results = {
json: null,
yaml: null,
env: null
};
// Test JSON round-trip
console.log('π Testing JSON round-trip...');
const jsonImported = await makeRequest('/api/import/json', 'POST', { content: JSON.stringify(jsonExport) });
results.json = compareConfigurations(baseline, jsonImported);
// Test YAML round-trip
console.log('π Testing YAML round-trip...');
const yamlImported = await makeRequest('/api/import/yaml', 'POST', { content: yamlContent });
results.yaml = compareConfigurations(baseline, yamlImported);
// Test ENV round-trip
console.log('π Testing ENV round-trip...');
const envImported = await makeRequest('/api/import/env', 'POST', { content: envContent });
results.env = compareConfigurations(baseline, envImported);
// Print results
console.log('\n' + '='.repeat(60));
console.log('π ROUND-TRIP TEST RESULTS');
console.log('='.repeat(60) + '\n');
for (const [format, result] of Object.entries(results)) {
const formatName = format.toUpperCase();
const status = result.newFields.length === 0 && result.updatedFields.length === 0 ? 'β
PASS' : 'β FAIL';
console.log(`${formatName}: ${status}`);
if (result.newFields.length > 0) {
console.log(` β οΈ New fields: ${result.newFields.length}`);
result.newFields.forEach(field => console.log(` - ${field}`));
}
if (result.updatedFields.length > 0) {
console.log(` β οΈ Updated fields: ${result.updatedFields.length}`);
result.updatedFields.forEach(field => console.log(` - ${field.path}: ${JSON.stringify(field.baseline)} β ${JSON.stringify(field.imported)}`));
}
console.log('');
}
const allPassed = Object.values(results).every(r => r.newFields.length === 0 && r.updatedFields.length === 0);
// Write detailed results to file
fs.writeFileSync('/tmp/roundtrip-details.json', JSON.stringify(results, null, 2));
console.log('π Detailed results saved to /tmp/roundtrip-details.json\n');
if (allPassed) {
console.log('π ALL TESTS PASSED! Perfect round-trip parity achieved.');
} else {
console.log('β TESTS FAILED. Round-trip parity not achieved.');
process.exit(1);
}
}
function compareConfigurations(baseline, imported) {
const newFields = [];
const updatedFields = [];
function compare(basePath, baseVal, importedVal) {
if (importedVal === undefined || importedVal === null || importedVal === '') {
return;
}
if (baseVal === undefined || baseVal === null || baseVal === '') {
newFields.push(basePath);
return;
}
if (typeof importedVal === 'object' && !Array.isArray(importedVal)) {
for (const key in importedVal) {
compare(`${basePath}.${key}`, baseVal[key], importedVal[key]);
}
} else if (JSON.stringify(baseVal) !== JSON.stringify(importedVal)) {
updatedFields.push({ path: basePath, baseline: baseVal, imported: importedVal });
}
}
compare('root', baseline, imported);
return { newFields, updatedFields };
}
runRoundTripTest().catch(console.error);