Skip to content

Commit

Permalink
test(sdl): cover denom validation
Browse files Browse the repository at this point in the history
also improve basic yml templating with default values

refs akash-network/console#133
  • Loading branch information
ygrishajev committed May 10, 2024
1 parent e5332e9 commit 7057fa8
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 30 deletions.
2 changes: 2 additions & 0 deletions src/config/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ export const USDC_IBC_DENOMS: Record<NetworkId, string> = {
[SANDBOX_ID]: "ibc/12C6A0C374171B595A0A9E18B83FA09D295FB1F2D8C6DAA3AC28683471752D84",
[TESTNET_ID]: ""
};

export const AKT_DENOM = "uakt";
73 changes: 46 additions & 27 deletions src/sdl/SDL/SDL.spec.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,64 @@
import { faker } from "@faker-js/faker";
import template from "lodash/template";
import omit from "lodash/omit";

import { readYml, toYmlFragment } from "../../../test/yml";
import { readBasicSdl } from "../../../test/yml";
import { SdlValidationError } from "../../error";
import { SDL } from "./SDL";
import { v2ServiceImageCredentials } from "../types";

const createYML = template(readYml("sdl-hello-world-basic-with-creds"));
import { omit } from "lodash";
import { AKT_DENOM, SANDBOX_ID, USDC_IBC_DENOMS } from "../../config/network";

describe("SDL", () => {
describe("profiles placement pricing denomination", () => {
it.each([AKT_DENOM, USDC_IBC_DENOMS[SANDBOX_ID]])('should resolve a group with a valid "%s" denomination', denom => {
const yml = readBasicSdl({ denom });
const sdl = SDL.fromString(yml, "beta3", "sandbox");

expect(sdl.groups()).toMatchObject([
{
resources: [
{
price: {
denom: denom,
amount: "1000"
}
}
]
}
]);
});

it("should throw an error when denomination is invalid", () => {
const denom = "usdt";
const yml = readBasicSdl({ denom });

expect(() => SDL.fromString(yml, "beta3", "sandbox")).toThrow(
new SdlValidationError(`Invalid denom: "${denom}". Only uakt and ${USDC_IBC_DENOMS[SANDBOX_ID]} are supported.`)
);
});
});

describe("service image credentials", () => {
it("should resolve a service with valid credentials", () => {
const credentials = {
host: faker.internet.url(),
username: faker.internet.userName(),
password: faker.internet.password()
};
const yml = createYML({
credentials: toYmlFragment({ credentials }, { nestingLevel: 2 })
});
const sdl = SDL.fromString(yml, "beta3", "sandbox");
const sdl = SDL.fromString(readBasicSdl({ credentials }), "beta3", "sandbox");

expect(sdl.manifest()).toMatchObject([{ services: [{ credentials }] }]);
expect(sdl.manifest()).toMatchObject([
{
services: [
{
credentials
}
]
}
]);
});

it("should resolve a service without credentials", () => {
const yml = createYML({
credentials: ""
});
const sdl = SDL.fromString(yml, "beta3", "sandbox");
const sdl = SDL.fromString(readBasicSdl(), "beta3", "sandbox");
const group = sdl.manifest()[0];

if (!("services" in group)) {
Expand All @@ -52,34 +81,24 @@ describe("SDL", () => {
});

it.each(fields)('should throw an error when credentials are missing "%s"', field => {
const yml = createYML({
credentials: toYmlFragment({ credentials: omit(credentials, field) }, { nestingLevel: 2 })
});

expect(() => {
SDL.fromString(yml, "beta3", "sandbox");
SDL.fromString(readBasicSdl({ credentials: omit(credentials, field) }), "beta3", "sandbox");
}).toThrowError(new SdlValidationError(`service "web" credentials missing "${field}"`));
});

it.each(fields)('should throw an error when credentials "%s" is empty', field => {
credentials[field] = "";
const yml = createYML({
credentials: toYmlFragment({ credentials: omit(credentials, field) }, { nestingLevel: 2 })
});

expect(() => {
SDL.fromString(yml, "beta3", "sandbox");
SDL.fromString(readBasicSdl({ credentials }), "beta3", "sandbox");
}).toThrowError(new SdlValidationError(`service "web" credentials missing "${field}"`));
});

it.each(fields)('should throw an error when credentials "%s" contains spaces only', field => {
credentials[field] = " ";
const yml = createYML({
credentials: toYmlFragment({ credentials: omit(credentials, field) }, { nestingLevel: 2 })
});

expect(() => {
SDL.fromString(yml, "beta3", "sandbox");
SDL.fromString(readBasicSdl({ credentials }), "beta3", "sandbox");
}).toThrowError(new SdlValidationError(`service "web" credentials missing "${field}"`));
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/sdl/SDL/SDL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
import { convertCpuResourceString, convertResourceString } from "./../sizes";
import { default as stableStringify } from "json-stable-stringify";
import crypto from "node:crypto";
import { MAINNET_ID, USDC_IBC_DENOMS } from "../../config/network";
import { AKT_DENOM, MAINNET_ID, USDC_IBC_DENOMS } from "../../config/network";
import { NetworkId } from "../../types/network";
import { SdlValidationError } from "../../error";

Expand Down Expand Up @@ -180,7 +180,7 @@ export class SDL {
const denoms = this.groups()
.flatMap(g => g.resources)
.map(resource => resource.price.denom);
const invalidDenom = denoms.find(denom => denom !== "uakt" && denom !== usdcDenom);
const invalidDenom = denoms.find(denom => denom !== AKT_DENOM && denom !== usdcDenom);

SdlValidationError.assert(!invalidDenom, `Invalid denom: "${invalidDenom}". Only uakt and ${usdcDenom} are supported.`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ profiles:
dcloud:
pricing:
web:
denom: uakt
denom: ${denom}
amount: 1000

deployment:
Expand Down
27 changes: 27 additions & 0 deletions test/yml.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import fs from "fs";
import path from "path";
import { dump } from "js-yaml";
import { faker } from "@faker-js/faker";
import template from "lodash/template";
import memoize from "lodash/memoize";
import { AKT_DENOM } from "../src/config/network";
import { SANDBOX_ID, USDC_IBC_DENOMS } from "../src/config/network";
import { pick } from "lodash";

export const readYml = (name: string): string => {
return fs.readFileSync(path.resolve(__dirname, `./fixtures/${name}.yml`), "utf-8");
Expand All @@ -23,3 +29,24 @@ export const toYmlFragment = (object: YmlInputObject, options?: { nestingLevel:
.map(line => indentation + line)
.join("\n");
};

interface BasicSdlTemplateVariables {
denom?: string;
credentials?: {
host?: string;
username?: string;
password?: string;
};
}

const readBasicSdlTemplate = memoize(() => template(readYml("sdl-basic")));

export const readBasicSdl = (variables: BasicSdlTemplateVariables = {}): string => {
const createYML = readBasicSdlTemplate();
const ymlVars: Record<keyof BasicSdlTemplateVariables, string> = {
denom: variables.denom || faker.helpers.arrayElement([AKT_DENOM, USDC_IBC_DENOMS[SANDBOX_ID]]),
credentials: variables.credentials ? toYmlFragment(pick(variables, "credentials"), { nestingLevel: 2 }) : ""
};

return createYML(ymlVars);
};

0 comments on commit 7057fa8

Please sign in to comment.