@microsoft/terraform-cdk-constructs 1.3.0 → 1.4.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/.jsii +22673 -19618
- package/API.md +25592 -20586
- package/lib/azure-actiongroup/lib/action-group.js +1 -1
- package/lib/azure-activitylogalert/lib/activity-log-alert.js +1 -1
- package/lib/azure-aks/lib/aks-cluster.js +1 -1
- package/lib/azure-diagnosticsettings/lib/diagnostic-settings.js +1 -1
- package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.js +1 -1
- package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.js +1 -1
- package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.js +1 -1
- package/lib/azure-dnsresolver/lib/dns-resolver.js +1 -1
- package/lib/azure-dnsresolver/lib/inbound-endpoint.js +1 -1
- package/lib/azure-dnsresolver/lib/outbound-endpoint.js +1 -1
- package/lib/azure-dnszone/lib/dns-zone.js +1 -1
- package/lib/azure-metricalert/lib/metric-alert.js +1 -1
- package/lib/azure-networkinterface/lib/network-interface.js +1 -1
- package/lib/azure-networksecuritygroup/lib/network-security-group.js +1 -1
- package/lib/azure-policyassignment/lib/policy-assignment.d.ts +7 -0
- package/lib/azure-policyassignment/lib/policy-assignment.js +11 -2
- package/lib/azure-policydefinition/lib/policy-definition.d.ts +21 -0
- package/lib/azure-policydefinition/lib/policy-definition.js +40 -3
- package/lib/azure-policydefinition/test/policy-definition.spec.js +211 -1
- package/lib/azure-privatednszone/lib/private-dns-zone.js +1 -1
- package/lib/azure-privatednszonelink/lib/private-dns-zone-link.js +1 -1
- package/lib/azure-publicipaddress/lib/public-ip-address.js +1 -1
- package/lib/azure-resourcegroup/lib/resource-group.js +1 -1
- package/lib/azure-roleassignment/lib/role-assignment.js +1 -1
- package/lib/azure-roledefinition/lib/role-definition.js +1 -1
- package/lib/azure-storageaccount/lib/storage-account.js +1 -1
- package/lib/azure-subnet/lib/subnet.js +1 -1
- package/lib/azure-virtualmachine/lib/virtual-machine.js +1 -1
- package/lib/azure-virtualnetwork/lib/virtual-network.js +1 -1
- package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.js +1 -1
- package/lib/azure-virtualnetworkmanager/lib/index.d.ts +5 -0
- package/lib/azure-virtualnetworkmanager/lib/index.js +6 -1
- package/lib/azure-virtualnetworkmanager/lib/ipam-pool-schemas.d.ts +24 -0
- package/lib/azure-virtualnetworkmanager/lib/ipam-pool-schemas.js +169 -0
- package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr-schemas.d.ts +32 -0
- package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr-schemas.js +206 -0
- package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr.d.ts +170 -0
- package/lib/azure-virtualnetworkmanager/lib/ipam-pool-static-cidr.js +214 -0
- package/lib/azure-virtualnetworkmanager/lib/ipam-pool.d.ts +175 -0
- package/lib/azure-virtualnetworkmanager/lib/ipam-pool.js +206 -0
- package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.js +1 -1
- package/lib/azure-virtualnetworkmanager/lib/network-group.js +1 -1
- package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.js +1 -1
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.js +1 -1
- package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.js +1 -1
- package/lib/azure-virtualnetworkmanager/lib/utils/cidr-validator.d.ts +225 -0
- package/lib/azure-virtualnetworkmanager/lib/utils/cidr-validator.js +389 -0
- package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.d.ts +56 -0
- package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.js +29 -2
- package/lib/azure-virtualnetworkmanager/test/cidr-validator.spec.d.ts +6 -0
- package/lib/azure-virtualnetworkmanager/test/cidr-validator.spec.js +292 -0
- package/lib/azure-virtualnetworkmanager/test/ipam-pool-static-cidr.spec.d.ts +6 -0
- package/lib/azure-virtualnetworkmanager/test/ipam-pool-static-cidr.spec.js +430 -0
- package/lib/azure-virtualnetworkmanager/test/ipam-pool.spec.d.ts +6 -0
- package/lib/azure-virtualnetworkmanager/test/ipam-pool.spec.js +372 -0
- package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.d.ts +2 -1
- package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.js +30 -3
- package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.spec.js +105 -1
- package/lib/azure-vmss/lib/virtual-machine-scale-set.js +1 -1
- package/lib/core-azure/lib/azapi/azapi-resource.d.ts +28 -0
- package/lib/core-azure/lib/azapi/azapi-resource.js +60 -10
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-client-config/index.js +2 -2
- package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource/index.js +5 -5
- package/lib/core-azure/lib/azapi/providers-azapi/provider/index.js +1 -1
- package/lib/core-azure/lib/azapi/providers-azapi/resource/index.js +5 -5
- package/lib/core-azure/lib/azapi/providers-azapi/resource-action/index.js +3 -3
- package/lib/core-azure/lib/azapi/providers-azapi/update-resource/index.js +3 -3
- package/lib/core-azure/lib/azapi/schema-mapper/schema-mapper.js +1 -1
- package/lib/core-azure/lib/version-manager/api-version-manager.js +1 -1
- package/lib/core-azure/lib/version-manager/interfaces/version-interfaces.js +7 -7
- package/lib/testing/index.js +2 -2
- package/lib/testing/lib/cleanup.js +1 -1
- package/lib/testing/lib/metadata.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* IPAM Pool Static CIDR Tests
|
|
4
|
+
*
|
|
5
|
+
* Unit tests for the IPAM Pool Static CIDR construct
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const cdktf_1 = require("cdktf");
|
|
9
|
+
const cdktf = require("cdktf");
|
|
10
|
+
const ipam_pool_1 = require("../lib/ipam-pool");
|
|
11
|
+
const ipam_pool_static_cidr_1 = require("../lib/ipam-pool-static-cidr");
|
|
12
|
+
const virtual_network_manager_1 = require("../lib/virtual-network-manager");
|
|
13
|
+
describe("IpamPoolStaticCidr", () => {
|
|
14
|
+
let app;
|
|
15
|
+
let stack;
|
|
16
|
+
let manager;
|
|
17
|
+
let pool;
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
app = cdktf_1.Testing.app();
|
|
20
|
+
stack = new cdktf.TerraformStack(app, "test-stack");
|
|
21
|
+
manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
|
|
22
|
+
name: "test-manager",
|
|
23
|
+
location: "eastus",
|
|
24
|
+
resourceGroupId: "/subscriptions/test/resourceGroups/rg",
|
|
25
|
+
networkManagerScopes: {
|
|
26
|
+
subscriptions: ["/subscriptions/test"],
|
|
27
|
+
},
|
|
28
|
+
networkManagerScopeAccesses: ["Connectivity"],
|
|
29
|
+
});
|
|
30
|
+
pool = new ipam_pool_1.IpamPool(stack, "TestPool", {
|
|
31
|
+
name: "test-pool",
|
|
32
|
+
location: "eastus",
|
|
33
|
+
networkManagerId: manager.id,
|
|
34
|
+
addressPrefixes: ["10.0.0.0/8"],
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe("Basic Instantiation", () => {
|
|
38
|
+
it("should create static CIDR with required properties", () => {
|
|
39
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
40
|
+
name: "test-cidr",
|
|
41
|
+
ipamPoolId: pool.id,
|
|
42
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
43
|
+
});
|
|
44
|
+
expect(staticCidr).toBeInstanceOf(ipam_pool_static_cidr_1.IpamPoolStaticCidr);
|
|
45
|
+
expect(staticCidr.props.addressPrefixes).toEqual(["10.0.1.0/24"]);
|
|
46
|
+
expect(staticCidr.props.name).toBe("test-cidr");
|
|
47
|
+
expect(staticCidr.addressPrefixes).toEqual(["10.0.1.0/24"]);
|
|
48
|
+
});
|
|
49
|
+
it("should create static CIDR with description", () => {
|
|
50
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
51
|
+
name: "test-cidr",
|
|
52
|
+
ipamPoolId: pool.id,
|
|
53
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
54
|
+
description: "Reserved for web servers",
|
|
55
|
+
});
|
|
56
|
+
expect(staticCidr.props.description).toBe("Reserved for web servers");
|
|
57
|
+
});
|
|
58
|
+
it("should auto-calculate IP count when not provided", () => {
|
|
59
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
60
|
+
name: "test-cidr",
|
|
61
|
+
ipamPoolId: pool.id,
|
|
62
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
63
|
+
});
|
|
64
|
+
expect(staticCidr.calculatedAddressCount).toBe(256);
|
|
65
|
+
});
|
|
66
|
+
it("should create multiple static CIDRs in same pool", () => {
|
|
67
|
+
const cidr1 = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "StaticCidr1", {
|
|
68
|
+
name: "cidr-1",
|
|
69
|
+
ipamPoolId: pool.id,
|
|
70
|
+
addressPrefixes: ["10.1.0.0/24"],
|
|
71
|
+
});
|
|
72
|
+
const cidr2 = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "StaticCidr2", {
|
|
73
|
+
name: "cidr-2",
|
|
74
|
+
ipamPoolId: pool.id,
|
|
75
|
+
addressPrefixes: ["10.2.0.0/24"],
|
|
76
|
+
});
|
|
77
|
+
expect(cidr1.props.name).toBe("cidr-1");
|
|
78
|
+
expect(cidr2.props.name).toBe("cidr-2");
|
|
79
|
+
expect(cidr1.addressPrefixes).toEqual(["10.1.0.0/24"]);
|
|
80
|
+
expect(cidr2.addressPrefixes).toEqual(["10.2.0.0/24"]);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
describe("CIDR Validation", () => {
|
|
84
|
+
it("should throw error for invalid CIDR format", () => {
|
|
85
|
+
expect(() => {
|
|
86
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
87
|
+
name: "test-cidr",
|
|
88
|
+
ipamPoolId: pool.id,
|
|
89
|
+
addressPrefixes: ["10.0.0.0/33"],
|
|
90
|
+
});
|
|
91
|
+
}).toThrow(/Invalid address prefix/i);
|
|
92
|
+
});
|
|
93
|
+
it("should throw error for missing CIDR prefix", () => {
|
|
94
|
+
expect(() => {
|
|
95
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
96
|
+
name: "test-cidr",
|
|
97
|
+
ipamPoolId: pool.id,
|
|
98
|
+
addressPrefixes: ["10.0.0.0"],
|
|
99
|
+
});
|
|
100
|
+
}).toThrow(/Invalid address prefix/i);
|
|
101
|
+
});
|
|
102
|
+
it("should throw error for invalid octets", () => {
|
|
103
|
+
expect(() => {
|
|
104
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
105
|
+
name: "test-cidr",
|
|
106
|
+
ipamPoolId: pool.id,
|
|
107
|
+
addressPrefixes: ["256.0.0.0/24"],
|
|
108
|
+
});
|
|
109
|
+
}).toThrow(/Invalid address prefix/i);
|
|
110
|
+
});
|
|
111
|
+
it("should throw error for empty address prefix", () => {
|
|
112
|
+
expect(() => {
|
|
113
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
114
|
+
name: "test-cidr",
|
|
115
|
+
ipamPoolId: pool.id,
|
|
116
|
+
addressPrefixes: [""],
|
|
117
|
+
});
|
|
118
|
+
}).toThrow(/Address prefix is required/i);
|
|
119
|
+
});
|
|
120
|
+
it("should accept valid CIDR with different prefix lengths", () => {
|
|
121
|
+
const cidr16 = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "Cidr16", {
|
|
122
|
+
name: "cidr-16",
|
|
123
|
+
ipamPoolId: pool.id,
|
|
124
|
+
addressPrefixes: ["10.1.0.0/16"],
|
|
125
|
+
});
|
|
126
|
+
const cidr24 = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "Cidr24", {
|
|
127
|
+
name: "cidr-24",
|
|
128
|
+
ipamPoolId: pool.id,
|
|
129
|
+
addressPrefixes: ["10.2.0.0/24"],
|
|
130
|
+
});
|
|
131
|
+
const cidr32 = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "Cidr32", {
|
|
132
|
+
name: "cidr-32",
|
|
133
|
+
ipamPoolId: pool.id,
|
|
134
|
+
addressPrefixes: ["10.3.0.1/32"],
|
|
135
|
+
});
|
|
136
|
+
expect(cidr16.calculatedAddressCount).toBe(65536);
|
|
137
|
+
expect(cidr24.calculatedAddressCount).toBe(256);
|
|
138
|
+
expect(cidr32.calculatedAddressCount).toBe(1);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe("IP Address Count Calculation", () => {
|
|
142
|
+
it("should calculate correct count for /24 CIDR", () => {
|
|
143
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
144
|
+
name: "test-cidr",
|
|
145
|
+
ipamPoolId: pool.id,
|
|
146
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
147
|
+
});
|
|
148
|
+
expect(staticCidr.calculatedAddressCount).toBe(256);
|
|
149
|
+
});
|
|
150
|
+
it("should calculate correct count for /16 CIDR", () => {
|
|
151
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
152
|
+
name: "test-cidr",
|
|
153
|
+
ipamPoolId: pool.id,
|
|
154
|
+
addressPrefixes: ["10.1.0.0/16"],
|
|
155
|
+
});
|
|
156
|
+
expect(staticCidr.calculatedAddressCount).toBe(65536);
|
|
157
|
+
});
|
|
158
|
+
it("should calculate correct count for /8 CIDR", () => {
|
|
159
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
160
|
+
name: "test-cidr",
|
|
161
|
+
ipamPoolId: pool.id,
|
|
162
|
+
addressPrefixes: ["10.0.0.0/8"],
|
|
163
|
+
});
|
|
164
|
+
expect(staticCidr.calculatedAddressCount).toBe(16777216);
|
|
165
|
+
});
|
|
166
|
+
it("should calculate correct count for /32 CIDR", () => {
|
|
167
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
168
|
+
name: "test-cidr",
|
|
169
|
+
ipamPoolId: pool.id,
|
|
170
|
+
addressPrefixes: ["10.0.0.1/32"],
|
|
171
|
+
});
|
|
172
|
+
expect(staticCidr.calculatedAddressCount).toBe(1);
|
|
173
|
+
});
|
|
174
|
+
it("should calculate correct count for /29 CIDR", () => {
|
|
175
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
176
|
+
name: "test-cidr",
|
|
177
|
+
ipamPoolId: pool.id,
|
|
178
|
+
addressPrefixes: ["10.0.0.0/29"],
|
|
179
|
+
});
|
|
180
|
+
expect(staticCidr.calculatedAddressCount).toBe(8);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
describe("Parent-Child Relationship", () => {
|
|
184
|
+
it("should correctly resolve parent pool ID", () => {
|
|
185
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
186
|
+
name: "test-cidr",
|
|
187
|
+
ipamPoolId: pool.id,
|
|
188
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
189
|
+
});
|
|
190
|
+
expect(staticCidr.props.ipamPoolId).toBe(pool.id);
|
|
191
|
+
});
|
|
192
|
+
it("should create static CIDR with direct pool ID reference", () => {
|
|
193
|
+
const poolId = "/subscriptions/test/resourceGroups/rg/providers/Microsoft.Network/networkManagers/vnm/ipamPools/test-pool";
|
|
194
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
195
|
+
name: "test-cidr",
|
|
196
|
+
ipamPoolId: poolId,
|
|
197
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
198
|
+
});
|
|
199
|
+
expect(staticCidr.props.ipamPoolId).toBe(poolId);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
describe("Terraform Outputs", () => {
|
|
203
|
+
it("should create proper Terraform outputs", () => {
|
|
204
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
205
|
+
name: "test-cidr",
|
|
206
|
+
ipamPoolId: pool.id,
|
|
207
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
208
|
+
});
|
|
209
|
+
expect(staticCidr.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
210
|
+
expect(staticCidr.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
211
|
+
expect(staticCidr.addressPrefixOutput).toBeInstanceOf(cdktf.TerraformOutput);
|
|
212
|
+
});
|
|
213
|
+
it("should have correct output logical IDs", () => {
|
|
214
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
215
|
+
name: "test-cidr",
|
|
216
|
+
ipamPoolId: pool.id,
|
|
217
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
218
|
+
});
|
|
219
|
+
const synthesized = cdktf_1.Testing.synth(stack);
|
|
220
|
+
const stackConfig = JSON.parse(synthesized);
|
|
221
|
+
expect(stackConfig.output).toBeDefined();
|
|
222
|
+
expect(stackConfig.output.id).toBeDefined();
|
|
223
|
+
expect(stackConfig.output.name).toBeDefined();
|
|
224
|
+
expect(stackConfig.output.addressPrefixes).toBeDefined();
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
describe("API Version Handling", () => {
|
|
228
|
+
it("should use default API version", () => {
|
|
229
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
230
|
+
name: "test-cidr",
|
|
231
|
+
ipamPoolId: pool.id,
|
|
232
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
233
|
+
});
|
|
234
|
+
expect(staticCidr.resolvedApiVersion).toBe("2024-05-01");
|
|
235
|
+
});
|
|
236
|
+
it("should use specified API version", () => {
|
|
237
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
238
|
+
name: "test-cidr",
|
|
239
|
+
ipamPoolId: pool.id,
|
|
240
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
241
|
+
apiVersion: "2023-11-01",
|
|
242
|
+
});
|
|
243
|
+
expect(staticCidr.resolvedApiVersion).toBe("2023-11-01");
|
|
244
|
+
});
|
|
245
|
+
it("should have correct resource type", () => {
|
|
246
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
247
|
+
name: "test-cidr",
|
|
248
|
+
ipamPoolId: pool.id,
|
|
249
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
250
|
+
});
|
|
251
|
+
const manifest = JSON.stringify(cdktf_1.Testing.synth(stack));
|
|
252
|
+
expect(manifest).toContain("Microsoft.Network/networkManagers/ipamPools/staticCidrs@2024-05-01");
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
describe("Helper Properties", () => {
|
|
256
|
+
it("should expose addressPrefixes property", () => {
|
|
257
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
258
|
+
name: "test-cidr",
|
|
259
|
+
ipamPoolId: pool.id,
|
|
260
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
261
|
+
});
|
|
262
|
+
expect(staticCidr.addressPrefixes).toEqual(["10.0.1.0/24"]);
|
|
263
|
+
});
|
|
264
|
+
it("should have provisioningState getter", () => {
|
|
265
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
266
|
+
name: "test-cidr",
|
|
267
|
+
ipamPoolId: pool.id,
|
|
268
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
269
|
+
});
|
|
270
|
+
expect(staticCidr.provisioningState).toBeDefined();
|
|
271
|
+
expect(typeof staticCidr.provisioningState).toBe("string");
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
describe("Lifecycle Management", () => {
|
|
275
|
+
it("should apply ignore changes for specified fields", () => {
|
|
276
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
277
|
+
name: "test-cidr",
|
|
278
|
+
ipamPoolId: pool.id,
|
|
279
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
280
|
+
ignoreChanges: ["description"],
|
|
281
|
+
});
|
|
282
|
+
const manifest = JSON.stringify(cdktf_1.Testing.synth(stack));
|
|
283
|
+
expect(manifest).toContain("ignore_changes");
|
|
284
|
+
});
|
|
285
|
+
it("should apply multiple ignore changes", () => {
|
|
286
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
287
|
+
name: "test-cidr",
|
|
288
|
+
ipamPoolId: pool.id,
|
|
289
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
290
|
+
ignoreChanges: ["description", "numberOfIPAddresses"],
|
|
291
|
+
});
|
|
292
|
+
const manifest = JSON.stringify(cdktf_1.Testing.synth(stack));
|
|
293
|
+
expect(manifest).toContain("ignore_changes");
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
describe("Terraform Synthesis", () => {
|
|
297
|
+
it("should synthesize valid Terraform configuration", () => {
|
|
298
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
299
|
+
name: "test-cidr",
|
|
300
|
+
ipamPoolId: pool.id,
|
|
301
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
302
|
+
description: "Test CIDR",
|
|
303
|
+
});
|
|
304
|
+
const output = cdktf_1.Testing.synth(stack);
|
|
305
|
+
expect(output).toBeDefined();
|
|
306
|
+
});
|
|
307
|
+
it("should include address prefix in resource body", () => {
|
|
308
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
309
|
+
name: "test-cidr",
|
|
310
|
+
ipamPoolId: pool.id,
|
|
311
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
312
|
+
});
|
|
313
|
+
const manifest = JSON.stringify(cdktf_1.Testing.synth(stack));
|
|
314
|
+
expect(manifest).toContain("10.0.1.0/24");
|
|
315
|
+
});
|
|
316
|
+
it("should include optional properties when specified", () => {
|
|
317
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
318
|
+
name: "test-cidr",
|
|
319
|
+
ipamPoolId: pool.id,
|
|
320
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
321
|
+
description: "Test description",
|
|
322
|
+
});
|
|
323
|
+
const manifest = JSON.stringify(cdktf_1.Testing.synth(stack));
|
|
324
|
+
expect(manifest).toContain("Test description");
|
|
325
|
+
});
|
|
326
|
+
it("should not include location in resource body", () => {
|
|
327
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
328
|
+
name: "test-cidr",
|
|
329
|
+
ipamPoolId: pool.id,
|
|
330
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
331
|
+
});
|
|
332
|
+
const manifest = JSON.stringify(cdktf_1.Testing.synth(stack));
|
|
333
|
+
// Child resources don't have location in body
|
|
334
|
+
expect(manifest).toContain("addressPrefixes");
|
|
335
|
+
expect(manifest).toContain("10.0.1.0/24");
|
|
336
|
+
});
|
|
337
|
+
it("should not include tags in resource body", () => {
|
|
338
|
+
new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
339
|
+
name: "test-cidr",
|
|
340
|
+
ipamPoolId: pool.id,
|
|
341
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
342
|
+
});
|
|
343
|
+
const manifest = JSON.stringify(cdktf_1.Testing.synth(stack));
|
|
344
|
+
// Child resources inherit tags from parent, not specified in body
|
|
345
|
+
expect(manifest).toContain("addressPrefixes");
|
|
346
|
+
expect(manifest).toContain("10.0.1.0/24");
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
describe("Edge Cases", () => {
|
|
350
|
+
it("should handle /32 prefix (single IP)", () => {
|
|
351
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
352
|
+
name: "test-cidr",
|
|
353
|
+
ipamPoolId: pool.id,
|
|
354
|
+
addressPrefixes: ["10.0.0.1/32"],
|
|
355
|
+
});
|
|
356
|
+
expect(staticCidr.calculatedAddressCount).toBe(1);
|
|
357
|
+
});
|
|
358
|
+
it("should handle /8 prefix (large block)", () => {
|
|
359
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
360
|
+
name: "test-cidr",
|
|
361
|
+
ipamPoolId: pool.id,
|
|
362
|
+
addressPrefixes: ["10.0.0.0/8"],
|
|
363
|
+
});
|
|
364
|
+
expect(staticCidr.calculatedAddressCount).toBe(16777216);
|
|
365
|
+
});
|
|
366
|
+
it("should handle maximum valid name length", () => {
|
|
367
|
+
const longName = "a".repeat(64);
|
|
368
|
+
const staticCidr = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "TestStaticCidr", {
|
|
369
|
+
name: longName,
|
|
370
|
+
ipamPoolId: pool.id,
|
|
371
|
+
addressPrefixes: ["10.0.1.0/24"],
|
|
372
|
+
});
|
|
373
|
+
expect(staticCidr.props.name).toBe(longName);
|
|
374
|
+
});
|
|
375
|
+
it("should handle private IP ranges", () => {
|
|
376
|
+
const cidr1 = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "Cidr1", {
|
|
377
|
+
name: "cidr-1",
|
|
378
|
+
ipamPoolId: pool.id,
|
|
379
|
+
addressPrefixes: ["10.0.0.0/8"],
|
|
380
|
+
});
|
|
381
|
+
const cidr2 = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "Cidr2", {
|
|
382
|
+
name: "cidr-2",
|
|
383
|
+
ipamPoolId: pool.id,
|
|
384
|
+
addressPrefixes: ["172.16.0.0/12"],
|
|
385
|
+
});
|
|
386
|
+
const cidr3 = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "Cidr3", {
|
|
387
|
+
name: "cidr-3",
|
|
388
|
+
ipamPoolId: pool.id,
|
|
389
|
+
addressPrefixes: ["192.168.0.0/16"],
|
|
390
|
+
});
|
|
391
|
+
expect(cidr1.calculatedAddressCount).toBe(16777216);
|
|
392
|
+
expect(cidr2.calculatedAddressCount).toBe(1048576);
|
|
393
|
+
expect(cidr3.calculatedAddressCount).toBe(65536);
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
describe("Complex Scenarios", () => {
|
|
397
|
+
it("should create multiple static CIDRs with different sizes", () => {
|
|
398
|
+
const small = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "SmallCidr", {
|
|
399
|
+
name: "small-cidr",
|
|
400
|
+
ipamPoolId: pool.id,
|
|
401
|
+
addressPrefixes: ["10.1.0.0/28"],
|
|
402
|
+
description: "Small allocation",
|
|
403
|
+
});
|
|
404
|
+
const medium = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "MediumCidr", {
|
|
405
|
+
name: "medium-cidr",
|
|
406
|
+
ipamPoolId: pool.id,
|
|
407
|
+
addressPrefixes: ["10.2.0.0/24"],
|
|
408
|
+
description: "Medium allocation",
|
|
409
|
+
});
|
|
410
|
+
const large = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "LargeCidr", {
|
|
411
|
+
name: "large-cidr",
|
|
412
|
+
ipamPoolId: pool.id,
|
|
413
|
+
addressPrefixes: ["10.3.0.0/16"],
|
|
414
|
+
description: "Large allocation",
|
|
415
|
+
});
|
|
416
|
+
expect(small.calculatedAddressCount).toBe(16);
|
|
417
|
+
expect(medium.calculatedAddressCount).toBe(256);
|
|
418
|
+
expect(large.calculatedAddressCount).toBe(65536);
|
|
419
|
+
});
|
|
420
|
+
it("should calculate IP count correctly for single CIDR", () => {
|
|
421
|
+
const withoutCount = new ipam_pool_static_cidr_1.IpamPoolStaticCidr(stack, "WithoutCount", {
|
|
422
|
+
name: "without-count",
|
|
423
|
+
ipamPoolId: pool.id,
|
|
424
|
+
addressPrefixes: ["10.2.0.0/24"],
|
|
425
|
+
});
|
|
426
|
+
expect(withoutCount.calculatedAddressCount).toBe(256);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXBhbS1wb29sLXN0YXRpYy1jaWRyLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXp1cmUtdmlydHVhbG5ldHdvcmttYW5hZ2VyL3Rlc3QvaXBhbS1wb29sLXN0YXRpYy1jaWRyLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7O0dBSUc7O0FBRUgsaUNBQWdDO0FBQ2hDLCtCQUErQjtBQUMvQixnREFBNEM7QUFDNUMsd0VBQWtFO0FBQ2xFLDRFQUF1RTtBQUV2RSxRQUFRLENBQUMsb0JBQW9CLEVBQUUsR0FBRyxFQUFFO0lBQ2xDLElBQUksR0FBYyxDQUFDO0lBQ25CLElBQUksS0FBMkIsQ0FBQztJQUNoQyxJQUFJLE9BQThCLENBQUM7SUFDbkMsSUFBSSxJQUFjLENBQUM7SUFFbkIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxlQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDcEIsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDcEQsT0FBTyxHQUFHLElBQUksK0NBQXFCLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRTtZQUN4RCxJQUFJLEVBQUUsY0FBYztZQUNwQixRQUFRLEVBQUUsUUFBUTtZQUNsQixlQUFlLEVBQUUsdUNBQXVDO1lBQ3hELG9CQUFvQixFQUFFO2dCQUNwQixhQUFhLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQzthQUN2QztZQUNELDJCQUEyQixFQUFFLENBQUMsY0FBYyxDQUFDO1NBQzlDLENBQUMsQ0FBQztRQUNILElBQUksR0FBRyxJQUFJLG9CQUFRLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRTtZQUNyQyxJQUFJLEVBQUUsV0FBVztZQUNqQixRQUFRLEVBQUUsUUFBUTtZQUNsQixnQkFBZ0IsRUFBRSxPQUFPLENBQUMsRUFBRTtZQUM1QixlQUFlLEVBQUUsQ0FBQyxZQUFZLENBQUM7U0FD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dCI6WyIvKipcbiAqIElQQU0gUG9vbCBTdGF0aWMgQ0lEUiBUZXN0c1xuICpcbiAqIFVuaXQgdGVzdHMgZm9yIHRoZSBJUEFNIFBvb2wgU3RhdGljIENJRFIgY29uc3RydWN0XG4gKi9cblxuaW1wb3J0IHsgVGVzdGluZyB9IGZyb20gXCJjZGt0ZlwiO1xuaW1wb3J0ICogYXMgY2RrdGYgZnJvbSBcImNka3RmXCI7XG5pbXBvcnQgeyBJcGFtUG9vbCB9IGZyb20gXCIuLi9saWIvaXBhbS1wb29sXCI7XG5pbXBvcnQgeyBJcGFtUG9vbFN0YXRpY0NpZHIgfSBmcm9tIFwiLi4vbGliL2lwYW0tcG9vbC1zdGF0aWMtY2lkclwiO1xuaW1wb3J0IHsgVmlydHVhbE5ldHdvcmtNYW5hZ2VyIH0gZnJvbSBcIi4uL2xpYi92aXJ0dWFsLW5ldHdvcmstbWFuYWdlclwiO1xuXG5kZXNjcmliZShcIklwYW1Qb29sU3RhdGljQ2lkclwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IGNka3RmLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGt0Zi5UZXJyYWZvcm1TdGFjaztcbiAgbGV0IG1hbmFnZXI6IFZpcnR1YWxOZXR3b3JrTWFuYWdlcjtcbiAgbGV0IHBvb2w6IElwYW1Qb29sO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgbmFtZTogXCJ0ZXN0LW1hbmFnZXJcIixcbiAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgcmVzb3VyY2VHcm91cElkOiBcIi9zdWJzY3JpcHRpb25zL3Rlc3QvcmVzb3VyY2VHcm91cHMvcmdcIixcbiAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcIi9zdWJzY3JpcHRpb25zL3Rlc3RcIl0sXG4gICAgICB9LFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgfSk7XG4gICAgcG9vbCA9IG5ldyBJcGFtUG9vbChzdGFjaywgXCJUZXN0UG9vbFwiLCB7XG4gICAgICBuYW1lOiBcInRlc3QtcG9vbFwiLFxuICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjAuMC84XCJdLFxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIEluc3RhbnRpYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBzdGF0aWMgQ0lEUiB3aXRoIHJlcXVpcmVkIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyKS50b0JlSW5zdGFuY2VPZihJcGFtUG9vbFN0YXRpY0NpZHIpO1xuICAgICAgZXhwZWN0KHN0YXRpY0NpZHIucHJvcHMuYWRkcmVzc1ByZWZpeGVzKS50b0VxdWFsKFtcIjEwLjAuMS4wLzI0XCJdKTtcbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLnByb3BzLm5hbWUpLnRvQmUoXCJ0ZXN0LWNpZHJcIik7XG4gICAgICBleHBlY3Qoc3RhdGljQ2lkci5hZGRyZXNzUHJlZml4ZXMpLnRvRXF1YWwoW1wiMTAuMC4xLjAvMjRcIl0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHN0YXRpYyBDSURSIHdpdGggZGVzY3JpcHRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJSZXNlcnZlZCBmb3Igd2ViIHNlcnZlcnNcIixcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qoc3RhdGljQ2lkci5wcm9wcy5kZXNjcmlwdGlvbikudG9CZShcIlJlc2VydmVkIGZvciB3ZWIgc2VydmVyc1wiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGF1dG8tY2FsY3VsYXRlIElQIGNvdW50IHdoZW4gbm90IHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRpY0NpZHIgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qoc3RhdGljQ2lkci5jYWxjdWxhdGVkQWRkcmVzc0NvdW50KS50b0JlKDI1Nik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgbXVsdGlwbGUgc3RhdGljIENJRFJzIGluIHNhbWUgcG9vbFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjaWRyMSA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiU3RhdGljQ2lkcjFcIiwge1xuICAgICAgICBuYW1lOiBcImNpZHItMVwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjEuMC4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGNpZHIyID0gbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJTdGF0aWNDaWRyMlwiLCB7XG4gICAgICAgIG5hbWU6IFwiY2lkci0yXCIsXG4gICAgICAgIGlwYW1Qb29sSWQ6IHBvb2wuaWQsXG4gICAgICAgIGFkZHJlc3NQcmVmaXhlczogW1wiMTAuMi4wLjAvMjRcIl0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGNpZHIxLnByb3BzLm5hbWUpLnRvQmUoXCJjaWRyLTFcIik7XG4gICAgICBleHBlY3QoY2lkcjIucHJvcHMubmFtZSkudG9CZShcImNpZHItMlwiKTtcbiAgICAgIGV4cGVjdChjaWRyMS5hZGRyZXNzUHJlZml4ZXMpLnRvRXF1YWwoW1wiMTAuMS4wLjAvMjRcIl0pO1xuICAgICAgZXhwZWN0KGNpZHIyLmFkZHJlc3NQcmVmaXhlcykudG9FcXVhbChbXCIxMC4yLjAuMC8yNFwiXSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQ0lEUiBWYWxpZGF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCBDSURSIGZvcm1hdFwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICAgIGlwYW1Qb29sSWQ6IHBvb2wuaWQsXG4gICAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjAuMC8zM1wiXSxcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KC9JbnZhbGlkIGFkZHJlc3MgcHJlZml4L2kpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgdGhyb3cgZXJyb3IgZm9yIG1pc3NpbmcgQ0lEUiBwcmVmaXhcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJUZXN0U3RhdGljQ2lkclwiLCB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICAgIGFkZHJlc3NQcmVmaXhlczogW1wiMTAuMC4wLjBcIl0sXG4gICAgICAgIH0pO1xuICAgICAgfSkudG9UaHJvdygvSW52YWxpZCBhZGRyZXNzIHByZWZpeC9pKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIG9jdGV0c1wiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICAgIGlwYW1Qb29sSWQ6IHBvb2wuaWQsXG4gICAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIyNTYuMC4wLjAvMjRcIl0sXG4gICAgICAgIH0pO1xuICAgICAgfSkudG9UaHJvdygvSW52YWxpZCBhZGRyZXNzIHByZWZpeC9pKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHRocm93IGVycm9yIGZvciBlbXB0eSBhZGRyZXNzIHByZWZpeFwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICAgIGlwYW1Qb29sSWQ6IHBvb2wuaWQsXG4gICAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCJcIl0sXG4gICAgICAgIH0pO1xuICAgICAgfSkudG9UaHJvdygvQWRkcmVzcyBwcmVmaXggaXMgcmVxdWlyZWQvaSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBhY2NlcHQgdmFsaWQgQ0lEUiB3aXRoIGRpZmZlcmVudCBwcmVmaXggbGVuZ3Roc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjaWRyMTYgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIkNpZHIxNlwiLCB7XG4gICAgICAgIG5hbWU6IFwiY2lkci0xNlwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjEuMC4wLzE2XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGNpZHIyNCA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiQ2lkcjI0XCIsIHtcbiAgICAgICAgbmFtZTogXCJjaWRyLTI0XCIsXG4gICAgICAgIGlwYW1Qb29sSWQ6IHBvb2wuaWQsXG4gICAgICAgIGFkZHJlc3NQcmVmaXhlczogW1wiMTAuMi4wLjAvMjRcIl0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgY2lkcjMyID0gbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJDaWRyMzJcIiwge1xuICAgICAgICBuYW1lOiBcImNpZHItMzJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4zLjAuMS8zMlwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoY2lkcjE2LmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoNjU1MzYpO1xuICAgICAgZXhwZWN0KGNpZHIyNC5jYWxjdWxhdGVkQWRkcmVzc0NvdW50KS50b0JlKDI1Nik7XG4gICAgICBleHBlY3QoY2lkcjMyLmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoMSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiSVAgQWRkcmVzcyBDb3VudCBDYWxjdWxhdGlvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY2FsY3VsYXRlIGNvcnJlY3QgY291bnQgZm9yIC8yNCBDSURSXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRpY0NpZHIgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qoc3RhdGljQ2lkci5jYWxjdWxhdGVkQWRkcmVzc0NvdW50KS50b0JlKDI1Nik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjYWxjdWxhdGUgY29ycmVjdCBjb3VudCBmb3IgLzE2IENJRFJcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjEuMC4wLzE2XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoNjU1MzYpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY2FsY3VsYXRlIGNvcnJlY3QgY291bnQgZm9yIC84IENJRFJcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMC4wLzhcIl0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHN0YXRpY0NpZHIuY2FsY3VsYXRlZEFkZHJlc3NDb3VudCkudG9CZSgxNjc3NzIxNik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjYWxjdWxhdGUgY29ycmVjdCBjb3VudCBmb3IgLzMyIENJRFJcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMC4xLzMyXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoMSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjYWxjdWxhdGUgY29ycmVjdCBjb3VudCBmb3IgLzI5IENJRFJcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMC4wLzI5XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoOCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUGFyZW50LUNoaWxkIFJlbGF0aW9uc2hpcFwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY29ycmVjdGx5IHJlc29sdmUgcGFyZW50IHBvb2wgSURcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLnByb3BzLmlwYW1Qb29sSWQpLnRvQmUocG9vbC5pZCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgc3RhdGljIENJRFIgd2l0aCBkaXJlY3QgcG9vbCBJRCByZWZlcmVuY2VcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9vbElkID1cbiAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3Jlc291cmNlR3JvdXBzL3JnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay9uZXR3b3JrTWFuYWdlcnMvdm5tL2lwYW1Qb29scy90ZXN0LXBvb2xcIjtcbiAgICAgIGNvbnN0IHN0YXRpY0NpZHIgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbElkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLnByb3BzLmlwYW1Qb29sSWQpLnRvQmUocG9vbElkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJUZXJyYWZvcm0gT3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHByb3BlciBUZXJyYWZvcm0gb3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBzdGF0aWNDaWRyID0gbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJUZXN0U3RhdGljQ2lkclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1jaWRyXCIsXG4gICAgICAgIGlwYW1Qb29sSWQ6IHBvb2wuaWQsXG4gICAgICAgIGFkZHJlc3NQcmVmaXhlczogW1wiMTAuMC4xLjAvMjRcIl0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHN0YXRpY0NpZHIuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3Qoc3RhdGljQ2lkci5uYW1lT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KHN0YXRpY0NpZHIuYWRkcmVzc1ByZWZpeE91dHB1dCkudG9CZUluc3RhbmNlT2YoXG4gICAgICAgIGNka3RmLlRlcnJhZm9ybU91dHB1dCxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYXZlIGNvcnJlY3Qgb3V0cHV0IGxvZ2ljYWwgSURzXCIsICgpID0+IHtcbiAgICAgIG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLm91dHB1dCkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5vdXRwdXQuaWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3Qoc3RhY2tDb25maWcub3V0cHV0Lm5hbWUpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3Qoc3RhY2tDb25maWcub3V0cHV0LmFkZHJlc3NQcmVmaXhlcykudG9CZURlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJBUEkgVmVyc2lvbiBIYW5kbGluZ1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgdXNlIGRlZmF1bHQgQVBJIHZlcnNpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjQtMDUtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2Ugc3BlY2lmaWVkIEFQSSB2ZXJzaW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRpY0NpZHIgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHN0YXRpY0NpZHIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMy0xMS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgY29ycmVjdCByZXNvdXJjZSB0eXBlXCIsICgpID0+IHtcbiAgICAgIG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG1hbmlmZXN0ID0gSlNPTi5zdHJpbmdpZnkoVGVzdGluZy5zeW50aChzdGFjaykpO1xuICAgICAgZXhwZWN0KG1hbmlmZXN0KS50b0NvbnRhaW4oXG4gICAgICAgIFwiTWljcm9zb2Z0Lk5ldHdvcmsvbmV0d29ya01hbmFnZXJzL2lwYW1Qb29scy9zdGF0aWNDaWRyc0AyMDI0LTA1LTAxXCIsXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkhlbHBlciBQcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBleHBvc2UgYWRkcmVzc1ByZWZpeGVzIHByb3BlcnR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRpY0NpZHIgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qoc3RhdGljQ2lkci5hZGRyZXNzUHJlZml4ZXMpLnRvRXF1YWwoW1wiMTAuMC4xLjAvMjRcIl0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGF2ZSBwcm92aXNpb25pbmdTdGF0ZSBnZXR0ZXJcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLnByb3Zpc2lvbmluZ1N0YXRlKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHR5cGVvZiBzdGF0aWNDaWRyLnByb3Zpc2lvbmluZ1N0YXRlKS50b0JlKFwic3RyaW5nXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkxpZmVjeWNsZSBNYW5hZ2VtZW50XCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBhcHBseSBpZ25vcmUgY2hhbmdlcyBmb3Igc3BlY2lmaWVkIGZpZWxkc1wiLCAoKSA9PiB7XG4gICAgICBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgICAgaWdub3JlQ2hhbmdlczogW1wiZGVzY3JpcHRpb25cIl0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgbWFuaWZlc3QgPSBKU09OLnN0cmluZ2lmeShUZXN0aW5nLnN5bnRoKHN0YWNrKSk7XG4gICAgICBleHBlY3QobWFuaWZlc3QpLnRvQ29udGFpbihcImlnbm9yZV9jaGFuZ2VzXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgYXBwbHkgbXVsdGlwbGUgaWdub3JlIGNoYW5nZXNcIiwgKCkgPT4ge1xuICAgICAgbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJUZXN0U3RhdGljQ2lkclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1jaWRyXCIsXG4gICAgICAgIGlwYW1Qb29sSWQ6IHBvb2wuaWQsXG4gICAgICAgIGFkZHJlc3NQcmVmaXhlczogW1wiMTAuMC4xLjAvMjRcIl0sXG4gICAgICAgIGlnbm9yZUNoYW5nZXM6IFtcImRlc2NyaXB0aW9uXCIsIFwibnVtYmVyT2ZJUEFkZHJlc3Nlc1wiXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBtYW5pZmVzdCA9IEpTT04uc3RyaW5naWZ5KFRlc3Rpbmcuc3ludGgoc3RhY2spKTtcbiAgICAgIGV4cGVjdChtYW5pZmVzdCkudG9Db250YWluKFwiaWdub3JlX2NoYW5nZXNcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiVGVycmFmb3JtIFN5bnRoZXNpc1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgc3ludGhlc2l6ZSB2YWxpZCBUZXJyYWZvcm0gY29uZmlndXJhdGlvblwiLCAoKSA9PiB7XG4gICAgICBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVGVzdCBDSURSXCIsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgb3V0cHV0ID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qob3V0cHV0KS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaW5jbHVkZSBhZGRyZXNzIHByZWZpeCBpbiByZXNvdXJjZSBib2R5XCIsICgpID0+IHtcbiAgICAgIG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMS4wLzI0XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG1hbmlmZXN0ID0gSlNPTi5zdHJpbmdpZnkoVGVzdGluZy5zeW50aChzdGFjaykpO1xuICAgICAgZXhwZWN0KG1hbmlmZXN0KS50b0NvbnRhaW4oXCIxMC4wLjEuMC8yNFwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGluY2x1ZGUgb3B0aW9uYWwgcHJvcGVydGllcyB3aGVuIHNwZWNpZmllZFwiLCAoKSA9PiB7XG4gICAgICBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVGVzdCBkZXNjcmlwdGlvblwiLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG1hbmlmZXN0ID0gSlNPTi5zdHJpbmdpZnkoVGVzdGluZy5zeW50aChzdGFjaykpO1xuICAgICAgZXhwZWN0KG1hbmlmZXN0KS50b0NvbnRhaW4oXCJUZXN0IGRlc2NyaXB0aW9uXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgbm90IGluY2x1ZGUgbG9jYXRpb24gaW4gcmVzb3VyY2UgYm9keVwiLCAoKSA9PiB7XG4gICAgICBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBtYW5pZmVzdCA9IEpTT04uc3RyaW5naWZ5KFRlc3Rpbmcuc3ludGgoc3RhY2spKTtcbiAgICAgIC8vIENoaWxkIHJlc291cmNlcyBkb24ndCBoYXZlIGxvY2F0aW9uIGluIGJvZHlcbiAgICAgIGV4cGVjdChtYW5pZmVzdCkudG9Db250YWluKFwiYWRkcmVzc1ByZWZpeGVzXCIpO1xuICAgICAgZXhwZWN0KG1hbmlmZXN0KS50b0NvbnRhaW4oXCIxMC4wLjEuMC8yNFwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIG5vdCBpbmNsdWRlIHRhZ3MgaW4gcmVzb3VyY2UgYm9keVwiLCAoKSA9PiB7XG4gICAgICBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBtYW5pZmVzdCA9IEpTT04uc3RyaW5naWZ5KFRlc3Rpbmcuc3ludGgoc3RhY2spKTtcbiAgICAgIC8vIENoaWxkIHJlc291cmNlcyBpbmhlcml0IHRhZ3MgZnJvbSBwYXJlbnQsIG5vdCBzcGVjaWZpZWQgaW4gYm9keVxuICAgICAgZXhwZWN0KG1hbmlmZXN0KS50b0NvbnRhaW4oXCJhZGRyZXNzUHJlZml4ZXNcIik7XG4gICAgICBleHBlY3QobWFuaWZlc3QpLnRvQ29udGFpbihcIjEwLjAuMS4wLzI0XCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkVkZ2UgQ2FzZXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGhhbmRsZSAvMzIgcHJlZml4IChzaW5nbGUgSVApXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRpY0NpZHIgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjAuMS8zMlwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qoc3RhdGljQ2lkci5jYWxjdWxhdGVkQWRkcmVzc0NvdW50KS50b0JlKDEpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIC84IHByZWZpeCAobGFyZ2UgYmxvY2spXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRpY0NpZHIgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlRlc3RTdGF0aWNDaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjAuMC84XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzdGF0aWNDaWRyLmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoMTY3NzcyMTYpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIG1heGltdW0gdmFsaWQgbmFtZSBsZW5ndGhcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgbG9uZ05hbWUgPSBcImFcIi5yZXBlYXQoNjQpO1xuICAgICAgY29uc3Qgc3RhdGljQ2lkciA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiVGVzdFN0YXRpY0NpZHJcIiwge1xuICAgICAgICBuYW1lOiBsb25nTmFtZSxcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4wLjEuMC8yNFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qoc3RhdGljQ2lkci5wcm9wcy5uYW1lKS50b0JlKGxvbmdOYW1lKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBwcml2YXRlIElQIHJhbmdlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjaWRyMSA9IG5ldyBJcGFtUG9vbFN0YXRpY0NpZHIoc3RhY2ssIFwiQ2lkcjFcIiwge1xuICAgICAgICBuYW1lOiBcImNpZHItMVwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjAuMC4wLzhcIl0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgY2lkcjIgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIkNpZHIyXCIsIHtcbiAgICAgICAgbmFtZTogXCJjaWRyLTJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxNzIuMTYuMC4wLzEyXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGNpZHIzID0gbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJDaWRyM1wiLCB7XG4gICAgICAgIG5hbWU6IFwiY2lkci0zXCIsXG4gICAgICAgIGlwYW1Qb29sSWQ6IHBvb2wuaWQsXG4gICAgICAgIGFkZHJlc3NQcmVmaXhlczogW1wiMTkyLjE2OC4wLjAvMTZcIl0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGNpZHIxLmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoMTY3NzcyMTYpO1xuICAgICAgZXhwZWN0KGNpZHIyLmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoMTA0ODU3Nik7XG4gICAgICBleHBlY3QoY2lkcjMuY2FsY3VsYXRlZEFkZHJlc3NDb3VudCkudG9CZSg2NTUzNik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQ29tcGxleCBTY2VuYXJpb3NcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBtdWx0aXBsZSBzdGF0aWMgQ0lEUnMgd2l0aCBkaWZmZXJlbnQgc2l6ZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgc21hbGwgPSBuZXcgSXBhbVBvb2xTdGF0aWNDaWRyKHN0YWNrLCBcIlNtYWxsQ2lkclwiLCB7XG4gICAgICAgIG5hbWU6IFwic21hbGwtY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjEuMC4wLzI4XCJdLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJTbWFsbCBhbGxvY2F0aW9uXCIsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgbWVkaXVtID0gbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJNZWRpdW1DaWRyXCIsIHtcbiAgICAgICAgbmFtZTogXCJtZWRpdW0tY2lkclwiLFxuICAgICAgICBpcGFtUG9vbElkOiBwb29sLmlkLFxuICAgICAgICBhZGRyZXNzUHJlZml4ZXM6IFtcIjEwLjIuMC4wLzI0XCJdLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJNZWRpdW0gYWxsb2NhdGlvblwiLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGxhcmdlID0gbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJMYXJnZUNpZHJcIiwge1xuICAgICAgICBuYW1lOiBcImxhcmdlLWNpZHJcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4zLjAuMC8xNlwiXSxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiTGFyZ2UgYWxsb2NhdGlvblwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChzbWFsbC5jYWxjdWxhdGVkQWRkcmVzc0NvdW50KS50b0JlKDE2KTtcbiAgICAgIGV4cGVjdChtZWRpdW0uY2FsY3VsYXRlZEFkZHJlc3NDb3VudCkudG9CZSgyNTYpO1xuICAgICAgZXhwZWN0KGxhcmdlLmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoNjU1MzYpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY2FsY3VsYXRlIElQIGNvdW50IGNvcnJlY3RseSBmb3Igc2luZ2xlIENJRFJcIiwgKCkgPT4ge1xuICAgICAgY29uc3Qgd2l0aG91dENvdW50ID0gbmV3IElwYW1Qb29sU3RhdGljQ2lkcihzdGFjaywgXCJXaXRob3V0Q291bnRcIiwge1xuICAgICAgICBuYW1lOiBcIndpdGhvdXQtY291bnRcIixcbiAgICAgICAgaXBhbVBvb2xJZDogcG9vbC5pZCxcbiAgICAgICAgYWRkcmVzc1ByZWZpeGVzOiBbXCIxMC4yLjAuMC8yNFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qod2l0aG91dENvdW50LmNhbGN1bGF0ZWRBZGRyZXNzQ291bnQpLnRvQmUoMjU2KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|