@onlineapps/conn-orch-validator 9.0.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +546 -0
- package/README.md +337 -19
- package/docs/DESIGN.md +32 -9
- package/manifests/biz-service.manifest.json +56 -6
- package/package.json +3 -2
- package/src/CookbookTestRunner.js +134 -22
- package/src/ValidationOrchestrator.js +312 -73
- package/src/cli/biz-ci-gate.js +191 -15
- package/src/cli/oa-sync-template.js +23 -8
- package/src/cli/oa-validate.js +70 -2
- package/src/index.js +21 -13
- package/src/lint/scripts/lintScripts.js +65 -18
- package/src/manifest/checks/composeRunnerBlock.js +37 -20
- package/src/manifest/checks/discoveryOrphan.js +2 -1
- package/src/manifest/checks/docsLintBridge.js +79 -21
- package/src/manifest/checks/gitTracked.js +14 -28
- package/src/manifest/checks/libraryPackage.js +3 -1
- package/src/manifest/checks/libraryWorkspace.js +18 -3
- package/src/manifest/checks/readmeRegion.js +9 -1
- package/src/manifest/checks/serviceConfig.js +29 -12
- package/src/manifest/checks/serviceDb.js +176 -7
- package/src/manifest/checks/serviceFiles.js +34 -7
- package/src/manifest/checks/serviceIdentityRows.js +3 -1
- package/src/manifest/checks/serviceRuntime.js +126 -1
- package/src/manifest/discovery.js +25 -7
- package/src/manifest/gitCheckout.js +84 -0
- package/src/manifest/runManifest.js +58 -7
- package/src/manifest/workspaceRoot.js +91 -5
- package/src/sync/serviceTemplate.js +76 -7
- package/src/sync/sharedEnv.js +11 -4
- package/src/sync/uniformFiles.js +91 -21
- package/src/utils/bizCiGateContract.js +25 -1
- package/src/utils/dbAccountGrants.js +126 -0
- package/src/utils/envContract.js +36 -6
- package/src/utils/envReads.js +102 -0
- package/src/utils/installContract.js +46 -5
- package/src/utils/libCompat.js +39 -19
- package/src/utils/preValidation.js +56 -11
- package/src/utils/stepFailure.js +106 -19
- package/src/utils/stepReferences.js +278 -0
- package/src/utils/testCoverageContract.js +60 -2
- package/src/utils/throwawaySchema.js +92 -7
- package/src/validatorIdentity.js +31 -0
- package/src/validators/ServiceStructureValidator.js +47 -15
- package/src/validators/ValidationProofGenerator.js +73 -34
- package/templates/business-service/.dockerignore +9 -1
- package/templates/business-service/.gitlab-ci.yml +199 -35
- package/templates/business-service/Dockerfile +49 -16
- package/templates/business-service/README.md +56 -9
- package/templates/business-service/config/env-templates/__SERVICE_NAME__.env +17 -5
- package/templates/business-service/config/env-templates/shared.env +8 -2
- package/templates/business-service/docker-compose.production.yml +9 -0
- package/templates/business-service/docker-compose.yml +17 -0
- package/templates/business-service/docs/80-setup/PLATFORM_MATRIX.md +1 -1
- package/templates/business-service/docs/80-setup/VALIDATION.md +1 -1
- package/templates/business-service/jest.config.js +9 -1
- package/templates/business-service/package.json.template +1 -1
- package/src/mocks/MockStorage.js +0 -188
|
@@ -23,7 +23,7 @@ Every command runs from the repository root (`api_biz/__SERVICE_NAME__/`).
|
|
|
23
23
|
node node_modules/@onlineapps/conn-orch-validator/src/cli/biz-ci-gate.js verify-contract
|
|
24
24
|
|
|
25
25
|
# 2 — unit suite, in the one-shot runner beside the service
|
|
26
|
-
npm run test:container
|
|
26
|
+
npm run test:unit:container
|
|
27
27
|
|
|
28
28
|
# 3 — cookbooks, in the same runner (it has the env files)
|
|
29
29
|
npm run test:cookbooks:container
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
module.exports = {
|
|
2
2
|
testEnvironment: 'node',
|
|
3
3
|
testMatch: ['**/tests/**/*.test.js'],
|
|
4
|
-
|
|
4
|
+
// 120 s, because the limit is there to catch a test that HANGS and not a
|
|
5
|
+
// queue for the processor: on the shared dev machine (load average 47-94,
|
|
6
|
+
// the runners of several services at once) five integration suites failed in
|
|
7
|
+
// beforeAll at the previous 30 s while each of them passed when run alone,
|
|
8
|
+
// and the whole run passed at 180 s (BIZ-converter, d.580). The number is the
|
|
9
|
+
// platform's, not a service's - row F-JEST holds this file byte for byte.
|
|
10
|
+
testTimeout: 120000,
|
|
11
|
+
// One suite at a time, which is what the runner's memory norm assumes
|
|
12
|
+
// (api/docs/governance/confirmations/biz-memory-limits.md 001).
|
|
5
13
|
maxWorkers: 1
|
|
6
14
|
};
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"test:ci": "jest",
|
|
14
14
|
"test:unit": "jest tests/unit",
|
|
15
15
|
"test:all": "npm run test:unit",
|
|
16
|
-
"test:container": "docker compose run --rm __CONTAINER_NAME___tests npm run test:unit",
|
|
16
|
+
"test:unit:container": "docker compose run --rm __CONTAINER_NAME___tests npm run test:unit",
|
|
17
17
|
"test:all:container": "docker compose run --rm __CONTAINER_NAME___tests npm run test:all",
|
|
18
18
|
"test:coverage": "jest --coverage",
|
|
19
19
|
"test:cookbooks": "node node_modules/@onlineapps/conn-orch-validator/src/cli/biz-ci-gate.js run-prevalidation",
|
package/src/mocks/MockStorage.js
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* MockStorage - Simulates MinIO/S3 storage for testing
|
|
5
|
-
*/
|
|
6
|
-
class MockStorage {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.buckets = {};
|
|
9
|
-
this.metadata = {};
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Create bucket
|
|
14
|
-
*/
|
|
15
|
-
async createBucket(bucketName) {
|
|
16
|
-
if (!this.buckets[bucketName]) {
|
|
17
|
-
this.buckets[bucketName] = {};
|
|
18
|
-
}
|
|
19
|
-
return { success: true };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Put object
|
|
24
|
-
*/
|
|
25
|
-
async put(bucket, key, content, options = {}) {
|
|
26
|
-
if (!this.buckets[bucket]) {
|
|
27
|
-
await this.createBucket(bucket);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const data = typeof content === 'object' ? JSON.stringify(content) : content;
|
|
31
|
-
|
|
32
|
-
this.buckets[bucket][key] = {
|
|
33
|
-
content: data,
|
|
34
|
-
contentType: options.contentType || 'application/json',
|
|
35
|
-
metadata: options.metadata || {},
|
|
36
|
-
timestamp: Date.now(),
|
|
37
|
-
size: data.length
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// Store metadata separately for querying
|
|
41
|
-
if (!this.metadata[bucket]) {
|
|
42
|
-
this.metadata[bucket] = {};
|
|
43
|
-
}
|
|
44
|
-
this.metadata[bucket][key] = {
|
|
45
|
-
size: data.length,
|
|
46
|
-
lastModified: Date.now(),
|
|
47
|
-
contentType: options.contentType || 'application/json'
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
success: true,
|
|
52
|
-
etag: `mock-etag-${Date.now()}`,
|
|
53
|
-
location: `${bucket}/${key}`
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Get object
|
|
59
|
-
*/
|
|
60
|
-
async get(bucket, key) {
|
|
61
|
-
if (!this.buckets[bucket] || !this.buckets[bucket][key]) {
|
|
62
|
-
throw new Error(`[MockStorage] Object not found: ${bucket}/${key} - Expected the object to have `
|
|
63
|
-
+ 'been stored first. Fix: put(bucket, key, content) in the test setup before reading it.');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const obj = this.buckets[bucket][key];
|
|
67
|
-
let content = obj.content;
|
|
68
|
-
|
|
69
|
-
// Try to parse JSON if content type suggests it
|
|
70
|
-
if (obj.contentType === 'application/json' && typeof content === 'string') {
|
|
71
|
-
try {
|
|
72
|
-
content = JSON.parse(content);
|
|
73
|
-
} catch (e) {
|
|
74
|
-
// Keep as string if parsing fails
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
content,
|
|
80
|
-
metadata: obj.metadata,
|
|
81
|
-
contentType: obj.contentType,
|
|
82
|
-
size: obj.size,
|
|
83
|
-
lastModified: obj.timestamp
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Delete object
|
|
89
|
-
*/
|
|
90
|
-
async delete(bucket, key) {
|
|
91
|
-
if (this.buckets[bucket]) {
|
|
92
|
-
delete this.buckets[bucket][key];
|
|
93
|
-
if (this.metadata[bucket]) {
|
|
94
|
-
delete this.metadata[bucket][key];
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return { success: true };
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* List objects in bucket
|
|
102
|
-
*/
|
|
103
|
-
async list(bucket, prefix = '', limit = 1000) {
|
|
104
|
-
if (!this.buckets[bucket]) {
|
|
105
|
-
return { objects: [] };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const objects = Object.keys(this.buckets[bucket])
|
|
109
|
-
.filter(key => key.startsWith(prefix))
|
|
110
|
-
.slice(0, limit)
|
|
111
|
-
.map(key => ({
|
|
112
|
-
key,
|
|
113
|
-
size: this.buckets[bucket][key].size,
|
|
114
|
-
lastModified: this.buckets[bucket][key].timestamp
|
|
115
|
-
}));
|
|
116
|
-
|
|
117
|
-
return { objects };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Check if object exists
|
|
122
|
-
*/
|
|
123
|
-
async exists(bucket, key) {
|
|
124
|
-
return !!(this.buckets[bucket] && this.buckets[bucket][key]);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Get object metadata
|
|
129
|
-
*/
|
|
130
|
-
async getMetadata(bucket, key) {
|
|
131
|
-
if (!this.metadata[bucket] || !this.metadata[bucket][key]) {
|
|
132
|
-
throw new Error(`[MockStorage] Metadata not found: ${bucket}/${key} - Expected metadata written `
|
|
133
|
-
+ 'by put(). Fix: store the object with put(bucket, key, content) before reading its metadata.');
|
|
134
|
-
}
|
|
135
|
-
return this.metadata[bucket][key];
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Generate presigned URL (mock)
|
|
140
|
-
*/
|
|
141
|
-
async getPresignedUrl(bucket, key, expiresIn = 3600) {
|
|
142
|
-
return {
|
|
143
|
-
url: `http://mock-storage/${bucket}/${key}?token=mock-token-${Date.now()}`,
|
|
144
|
-
expiresAt: Date.now() + (expiresIn * 1000)
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Clear all data
|
|
150
|
-
*/
|
|
151
|
-
clear() {
|
|
152
|
-
this.buckets = {};
|
|
153
|
-
this.metadata = {};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Get storage stats
|
|
158
|
-
*/
|
|
159
|
-
getStats() {
|
|
160
|
-
const stats = {
|
|
161
|
-
bucketCount: Object.keys(this.buckets).length,
|
|
162
|
-
totalObjects: 0,
|
|
163
|
-
totalSize: 0
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
Object.values(this.buckets).forEach(bucket => {
|
|
167
|
-
Object.values(bucket).forEach(obj => {
|
|
168
|
-
stats.totalObjects++;
|
|
169
|
-
stats.totalSize += obj.size;
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
return stats;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Copy object
|
|
178
|
-
*/
|
|
179
|
-
async copy(sourceBucket, sourceKey, destBucket, destKey) {
|
|
180
|
-
const source = await this.get(sourceBucket, sourceKey);
|
|
181
|
-
return await this.put(destBucket, destKey, source.content, {
|
|
182
|
-
contentType: source.contentType,
|
|
183
|
-
metadata: source.metadata
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
module.exports = MockStorage;
|