Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/database/postgres/site-license/hook.test.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/**6* This tests the core of ./hook.ts7* It's not using it directly, though, because of the complex dependency of the database.8* The main purpose of this test is to simulate what happens, if first a partial set of licenses,9* and then one more license is fed through the quota function.10* There was a bug, where licenses were modified in place, and the second call to the quota function11* used the modified license, which led to very subtle but severe problems.12*13* The quota function uses a deep copy operation on all its arguments to avoid this.14*/1516// see packages/database/pool/pool.ts for where this name is also hard coded:17process.env.PGDATABASE = "smc_ephemeral_testing_database";1819import { isEqual } from "lodash";2021import getPool, { initEphemeralDatabase } from "@cocalc/database/pool";22import { quota_with_reasons, SiteLicenses } from "@cocalc/util/upgrades/quota";2324beforeAll(async () => {25await initEphemeralDatabase({});26}, 15000);2728afterAll(async () => {29await getPool().end();30});3132test("allow for much larger max_upgrades", () => {33const site_settings = {34default_quotas: {35internet: true,36idle_timeout: 1800,37mem: 2000,38cpu: 1,39cpu_oc: 20,40mem_oc: 10,41},42max_upgrades: {43disk_quota: 20000,44memory: 50000,45memory_request: 1000,46cores: 16,47network: 1,48cpu_shares: 1024,49mintime: 7776000,50member_host: 1,51ephemeral_state: 1,52ephemeral_disk: 1,53always_running: 1,54},55kucalc: "onprem",56datastore: true,57};5859const site_licenses: SiteLicenses = {60a: {61quota: { cpu: 2, ram: 13 },62},63b: {64quota: { cpu: 3, ram: 32 },65},66};6768const q1 = quota_with_reasons(69{},70{ userX: {} },71{ a: site_licenses.a },72site_settings,73);74expect(q1).toEqual({75quota: {76network: true,77member_host: false,78privileged: false,79gpu: false,80memory_request: 1000,81cpu_request: 0.1,82disk_quota: 3000,83memory_limit: 13000,84cpu_limit: 2,85idle_timeout: 1800,86always_running: false,87dedicated_vm: false,88dedicated_disks: [],89},90reasons: {},91});9293const q2 = quota_with_reasons(94{},95{ userX: {} },96site_licenses,97site_settings,98);99expect(q2).toEqual({100quota: {101always_running: false,102cpu_limit: 5,103cpu_request: 0.25,104dedicated_disks: [],105dedicated_vm: false,106disk_quota: 3000,107idle_timeout: 1800,108member_host: false,109memory_limit: 45000,110memory_request: 1000,111network: true,112privileged: false,113gpu: false,114},115reasons: {},116});117});118119test("two licenses", () => {120const site_settings = {121default_quotas: {122internet: true,123idle_timeout: 1800,124mem: 2000,125cpu: 1,126cpu_oc: 20,127mem_oc: 10,128},129max_upgrades: {130disk_quota: 20000,131memory: 50000,132memory_request: 1000,133cores: 16,134network: 1,135cpu_shares: 1024,136mintime: 7776000,137member_host: 1,138ephemeral_state: 1,139ephemeral_disk: 1,140always_running: 1,141},142kucalc: "onprem",143datastore: true,144};145146const site_licenses = {147a: {148quota: { cpu: 1, ram: 13 },149},150b: {151quota: { cpu: 3, ram: 32 },152},153};154155const q1 = quota_with_reasons(156{},157{ userX: {} },158{ a: site_licenses.a },159site_settings,160);161expect(q1).toEqual({162quota: {163network: true,164member_host: false,165privileged: false,166gpu: false,167memory_request: 1000,168cpu_request: 0.05,169disk_quota: 3000,170memory_limit: 13000,171cpu_limit: 1,172idle_timeout: 1800,173always_running: false,174dedicated_vm: false,175dedicated_disks: [],176},177reasons: {},178});179180const q2 = quota_with_reasons(181{},182{ userX: {} },183site_licenses,184site_settings,185);186expect(q1).toEqual({187quota: {188network: true,189member_host: false,190privileged: false,191gpu: false,192memory_request: 1000,193cpu_request: 0.05,194disk_quota: 3000,195memory_limit: 13000,196cpu_limit: 1,197idle_timeout: 1800,198always_running: false,199dedicated_vm: false,200dedicated_disks: [],201},202reasons: {},203});204205expect(q2).toEqual({206quota: {207always_running: false,208cpu_limit: 4,209cpu_request: 0.2,210dedicated_disks: [],211dedicated_vm: false,212disk_quota: 3000,213idle_timeout: 1800,214member_host: false,215memory_limit: 45000,216memory_request: 1000,217network: true,218privileged: false,219gpu: false,220},221reasons: {},222});223224// in particular, this implies that the second license indeed HAS an effect and hence will be used.225expect(isEqual(q1, q2)).toBe(false);226});227228// TODO the test below would be very important to get to work, but the call to the site_license_hook has no effect at all229230// describe("site_license_hook", () => {231// const pool = getPool();232// const account_id = uuid();233// const license_id_1 = uuid();234// const license_id_2 = uuid();235236// let project_id;237// test("creates a project", async () => {238// project_id = await createProject({239// account_id,240// title: "Test Project",241// });242// });243244// test("setup project license", async () => {245// const site_licenses_data: SiteLicenses = {246// [license_id_1]: {247// quota: {248// dedicated_disk: { speed: "standard", size_gb: 128, name: "bar" },249// },250// },251// [license_id_2]: {252// quota: {253// ram: 2,254// cpu: 1,255// disk: 3,256// always_running: true,257// member: true,258// user: "academic",259// },260// },261// };262263// await pool.query(264// "UPDATE projects SET site_license=$1 WHERE project_id=$2",265// [site_licenses_data, project_id]266// );267// });268269// test("PAYGO mixes with dedicated disk", async () => {270// // run the hook -- "true" means there are PAYGO upgrades, different mode of how the license hook operates271// await site_license_hook(db(), project_id, true);272273// const { rows } = await pool.query(274// "SELECT * FROM projects WHERE project_id=$1",275// [project_id]276// );277// expect(rows.length).toBe(1);278// const site_licenses = rows[0].site_license;279// expect(rows[0].site_license).toEqual({280// [license_id_1]: {281// quota: {282// dedicated_disk: { name: "bar", size_gb: 128, speed: "standard" },283// },284// },285// [license_id_2]: {286// quota: {287// always_running: true,288// cpu: 1,289// disk: 3,290// member: true,291// ram: 2,292// user: "academic",293// },294// },295// });296297// const q = quota_with_reasons({}, { [account_id]: {} }, site_licenses);298// // projects on dedicated VMs get this quota299// expect(q).toEqual({300// quota: {301// always_running: false,302// cpu_limit: 1,303// cpu_request: 0.02,304// dedicated_disks: [305// {306// name: "bar",307// size_gb: 128,308// speed: "standard",309// },310// ],311// dedicated_vm: false,312// disk_quota: 3000,313// idle_timeout: 1800,314// member_host: false,315// memory_limit: 1000,316// memory_request: 200,317// network: false,318// privileged: false,gpu:false,319// },320// reasons: {},321// });322// });323// });324325326