UNPKG

@grouparoo/core

Version:
254 lines (213 loc) 7.73 kB
import fs from "fs"; import { helper } from "@grouparoo/spec-helper"; import { api, config } from "actionhero"; import fetch, { enableFetchMocks } from "jest-fetch-mock"; import { Telemetry } from "../../src/modules/telemetry"; import { TelemetryInitializer } from "../../src/initializers/telemetry"; import { ConfigUser } from "../../src/modules/configUser"; enableFetchMocks(); describe("modules/status", () => { helper.grouparooTestServer({ truncate: true, enableTestPlugin: true, resetSettings: true, }); beforeEach(async () => { await helper.truncate(); await api.resque.queue.connection.redis.flushdb(); process.env.GROUPAROO_RUN_MODE = "x"; config.telemetry.enabled = true; }); afterEach(() => { config.telemetry.enabled = false; fetch.resetMocks(); }); describe("telemetry module", () => { test("the telemetry object can be built", async () => { const { name, id, metrics, trigger } = await Telemetry.build("timer"); expect(name).toBe("My Grouparoo Cluster"); expect(id).toMatch(/^tcs_/); expect(trigger).toBe("timer"); expect(metrics).toContainEqual( expect.objectContaining({ collection: "cluster", topic: "workers", aggregation: "count", }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "cluster", topic: "resqueErrors", count: 0, // we hope }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "cluster", topic: "os", aggregation: "exact", }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "sequelize", topic: "dialect", aggregation: "exact", value: "postgres", }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "NODE_ENV", topic: "env", aggregation: "exact", value: "test", }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "GROUPAROO_RUN_MODE", topic: "env", aggregation: "exact", value: "x", }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "GROUPAROO_CLOUD", topic: "env", aggregation: "exact", value: "false", }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "GROUPAROO_DISTRIBUTION", topic: "env", aggregation: "exact", value: "unknown", }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "cluster", topic: "@grouparoo/core", aggregation: "exact", key: "version", }) ); expect(metrics).toContainEqual( expect.objectContaining({ collection: "totals", topic: "App", aggregation: "count", }) ); }); test("telemetry can be sent with an errors array", async () => { const { metrics } = await Telemetry.build("timer", [ "something is wrong", ]); const errorMetrics = metrics.filter((m) => m.topic === "error"); expect(errorMetrics.length).toEqual(1); expect(errorMetrics[0].value).toEqual("something is wrong"); }); describe("with errors", () => { let originalImplementation: typeof Telemetry.build; beforeAll(() => { config.telemetry.enabled = true; originalImplementation = Telemetry.build; const mockTelemetry = jest.fn(); mockTelemetry.mockImplementation(() => { throw new Error("OH NO"); }); Telemetry.build = mockTelemetry; }); afterAll(() => { config.telemetry.enabled = false; Telemetry.build = originalImplementation; }); test("by default, errors are not thrown", async () => { await Telemetry.send("timer"); // does not throw }); test("we will try to send errors about telemetry to the telemetry server if the send throws", async () => { await expect(Telemetry.send("timer", [], true)).rejects.toThrow( /OH NO/ ); expect(fetch).toHaveBeenCalledTimes(1); const args = fetch.mock.calls[0]; expect(args[0]).toBe( "https://telemetry.grouparoo.com/api/v1/telemetry" ); const payload = JSON.parse(args[1].body.toString()); expect(payload.name).toBe("My Grouparoo Cluster"); expect(payload.trigger).toBe("timer"); expect(payload.metrics.length).toBe(1); expect(payload.metrics[0].topic).toBe("error"); expect(payload.metrics[0].aggregation).toBe("exact"); expect(payload.metrics[0].value).toMatch("Error: OH NO"); expect(payload.metrics[0].value).toMatch( "core/__tests__/modules/telemetry.ts" ); expect(payload.metrics[0].value).not.toMatch( "/grouparoo/core/__tests__/modules/telemetry.ts" ); }); }); }); describe("telemetry initializer", () => { describe("telemetry on stop", () => { test("will send telemetry when stopping in cli:run mode", async () => { process.env.GROUPAROO_RUN_MODE = "cli:run"; config.telemetry.enabled = true; fetch.mockResponseOnce(JSON.stringify({ response: "FROM TEST" })); const instance = new TelemetryInitializer(); await instance.stop(); expect(fetch).toHaveBeenCalledTimes(1); expect(fetch).toHaveBeenCalledWith( "https://telemetry.grouparoo.com/api/v1/telemetry", expect.objectContaining({ method: "POST" }) ); const args = fetch.mock.calls[0]; const payload = JSON.parse(args[1].body as string); expect(payload.trigger).toBe("cli_run"); expect(payload.metrics.length).toBeGreaterThan(1); }); test("will not send telemetry when stopping via another run mode", async () => { fetch.mockResponseOnce(JSON.stringify({ response: "FROM TEST" })); const instance = new TelemetryInitializer(); await instance.stop(); expect(fetch).not.toHaveBeenCalled(); }); }); describe("telemetry on start", () => { afterEach(async () => { const localFile = await ConfigUser.localUserFilePath(); if (fs.existsSync(localFile)) fs.rmSync(localFile); }); test("will send telemetry when starting in cli:config mode", async () => { process.env.GROUPAROO_RUN_MODE = "cli:config"; config.telemetry.enabled = true; fetch.mockResponseOnce(JSON.stringify({ response: "FROM TEST" })); const instance = new TelemetryInitializer(); await instance.start(); expect(fetch).toHaveBeenCalledTimes(1); expect(fetch).toHaveBeenCalledWith( "https://telemetry.grouparoo.com/api/v1/telemetry", expect.objectContaining({ method: "POST" }) ); const args = fetch.mock.calls[0]; const payload = JSON.parse(args[1].body as string); expect(payload.trigger).toBe("cli_config"); expect(payload.metrics.length).toBeGreaterThan(1); }); test("will not send telemetry when starting via another run mode", async () => { fetch.mockResponseOnce(JSON.stringify({ response: "FROM TEST" })); const instance = new TelemetryInitializer(); await instance.start(); expect(fetch).not.toHaveBeenCalled(); }); }); }); });