Skip to content

Commit

Permalink
feat(tests): fix tests with big refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinMinkov committed Aug 16, 2023
1 parent 59971af commit 5f6403f
Show file tree
Hide file tree
Showing 16 changed files with 847 additions and 1,222 deletions.
13 changes: 13 additions & 0 deletions .env2
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
PORT=8080
LOG_LEVEL="info"
CORS_ORIGIN="*"

PG_CONN="postgres://postgres:password@localhost:5432/archive"

ENABLE_GRAPHIQL="true"
ENABLE_INTROSPECTION="true"

ENABLE_LOGGING="true"
ENABLE_JAEGER="true"
JAEGER_SERVICE_NAME="archive-api"
JAEGER_ENDPOINT='http://localhost:14268/api/traces'
13 changes: 11 additions & 2 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,23 @@ import { ArchiveNodeAdapter, DatabaseAdapter } from './db';

export interface GraphQLContext {
db_client: DatabaseAdapter;
[OPEN_TELEMETRY_GRAPHQL: symbol]: Span | undefined;
[OPEN_TELEMETRY_GRAPHQL: symbol]: Span | undefined; // Will only be set if we are in the scope of a GraphQL request
}

export async function buildContext(connectionString: string | undefined) {
const db_client = new ArchiveNodeAdapter(connectionString);
await db_client.checkSQLSchema();

return {
db_client,
};
}

export function getCurrentSpanFromGraphQLContext(context: GraphQLContext) {
const openTelemetrySymbol = Object.getOwnPropertySymbols(context).find(
(symbol) => symbol.description === 'OPEN_TELEMETRY_GRAPHQL'
);
if (!openTelemetrySymbol) {
return undefined;
}
return context[openTelemetrySymbol];
}
4 changes: 2 additions & 2 deletions src/db/archive-node-adapter/actions-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ class ActionsService {
}

async getActionData(input: ActionFilterOptionsInput): Promise<Actions> {
this.tracingService.startSpan('Actions SQL');
this.tracingService.startSpan('actions.SQL');
const rows = await this.executeActionsQuery(input);
this.tracingService.endSpan();

this.tracingService.startSpan('Actions Processing');
this.tracingService.startSpan('actions.processing');
const elementIdFieldValues = getElementIdFieldValues(rows);
const blocksWithTransactions = partitionBlocks(rows);
const actionsData = this.blocksToActions(
Expand Down
4 changes: 2 additions & 2 deletions src/db/archive-node-adapter/events-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ class EventsService {
}

async getEventData(input: EventFilterOptionsInput): Promise<Events> {
this.tracingService.startSpan('Events SQL');
this.tracingService.startSpan('events.SQL');
const rows = await this.executeEventsQuery(input);
this.tracingService.endSpan();

this.tracingService.startSpan('Events Processing');
this.tracingService.startSpan('events.processing');
const elementIdFieldValues = getElementIdFieldValues(rows);
const blocksWithTransactions = partitionBlocks(rows);
const eventsData = this.blocksToEvents(
Expand Down
31 changes: 20 additions & 11 deletions src/db/archive-node-adapter/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,26 +198,22 @@ function mapActionOrEvent(
elementIdFieldValues: FieldElementIdWithValueMap
) {
const data: (Event | Action)[] = [];

for (let i = 0; i < rows.length; i++) {
const { element_ids } = rows[i];
const currentValue = [];
for (const elementId of element_ids) {
const elementIdValue = elementIdFieldValues.get(elementId.toString());
if (elementIdValue === undefined) continue;
currentValue.push(elementIdValue);
}
const transactionInfo = createTransactionInfo(rows[i]);
const elementIdToFieldValues = getFieldValuesFromElementIds(
element_ids,
elementIdFieldValues
);

if (kind === 'event') {
const transactionInfo = createTransactionInfo(rows[i]);
const event = createEvent(currentValue, transactionInfo);
const event = createEvent(elementIdToFieldValues, transactionInfo);
data.push(event);
} else {
const { zkapp_account_update_id } = rows[i];
const transactionInfo = createTransactionInfo(rows[i]);
const action = createAction(
zkapp_account_update_id.toString(),
currentValue,
elementIdToFieldValues,
transactionInfo
);
data.push(action);
Expand All @@ -226,6 +222,19 @@ function mapActionOrEvent(
return data;
}

function getFieldValuesFromElementIds(
element_ids: number[],
elementIdFieldValues: FieldElementIdWithValueMap
) {
const elementIdToFieldValues = [];
for (const elementId of element_ids) {
const elementIdFieldValue = elementIdFieldValues.get(elementId.toString());
if (elementIdFieldValue === undefined) continue;
elementIdToFieldValues.push(elementIdFieldValue);
}
return elementIdToFieldValues;
}

function sortAndFilterBlocks<T extends { blockInfo: BlockInfo }>(
data: T[]
): T[] {
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const PORT = process.env.PORT || 8080;
['SIGINT', 'SIGTERM', 'SIGQUIT'].forEach((signal) => {
process.on(signal, () => server.close());
});

server.on('close', async () => {
await context.db_client.close();
process.exit(1);
Expand Down
26 changes: 9 additions & 17 deletions src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,26 @@ import { makeExecutableSchema } from '@graphql-tools/schema';
import { loadSchemaSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { Resolvers } from './resolvers-types';
import { getTraceInfoFromGraphQL } from './tracing';
import { getCurrentSpanFromGraphQLContext } from './context';
import { createTraceInfo, getGlobalTracer } from './tracing';

export const resolvers: Resolvers = {
Query: {
events: async (_, { input }, context) => {
const contextSymbols = Object.getOwnPropertySymbols(context);
const traceInfo = getTraceInfoFromGraphQL(context[contextSymbols?.[0]]);

if (!traceInfo) {
return context.db_client.getEvents(input);
}
const graphQLSpan = getCurrentSpanFromGraphQLContext(context);
const parentSpan = graphQLSpan || getGlobalTracer().startSpan('graphql');

return context.db_client.getEvents(input, {
traceInfo,
traceInfo: createTraceInfo(parentSpan),
});
},
actions: async (_, { input }, context) => {
const contextSymbols = Object.getOwnPropertySymbols(context);
const traceInfo = getTraceInfoFromGraphQL(context[contextSymbols?.[0]]);

if (!traceInfo) {
return context.db_client.getActions(input, {
traceInfo,
});
}
actions: async (_, { input }, context) => {
const graphQLSpan = getCurrentSpanFromGraphQLContext(context);
const parentSpan = graphQLSpan || getGlobalTracer().startSpan('graphql');

return context.db_client.getActions(input, {
traceInfo,
traceInfo: createTraceInfo(parentSpan),
});
},
},
Expand Down
7 changes: 6 additions & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useLogger } from '@envelop/core';
import { useGraphQlJit } from '@envelop/graphql-jit';
import { useDisableIntrospection } from '@envelop/disable-introspection';
import { useOpenTelemetry } from '@envelop/opentelemetry';
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';

import { request } from 'node:http';
import { inspect } from 'node:util';
Expand All @@ -16,8 +17,12 @@ const LOG_LEVEL = (process.env.LOG_LEVEL as LogLevel) || 'info';

function initJaegerProvider() {
let provider = undefined;
const options = {
endpoint: process.env.JAEGER_ENDPOINT,
};
const exporter = new JaegerExporter(options);
if (process.env.ENABLE_JAEGER) {
provider = buildProvider();
provider = buildProvider(exporter);
if (!process.env.JAEGER_ENDPOINT) {
throw new Error(
'Jaeger was enabled but no endpoint was specified. Please ensure that the Jaeger endpoint is properly configured and available.'
Expand Down
25 changes: 11 additions & 14 deletions src/tracing/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
import {
BatchSpanProcessor,
BasicTracerProvider,
SpanExporter,
} from '@opentelemetry/tracing';
import { context, trace, Span, Tracer, Context } from '@opentelemetry/api';

export function buildProvider() {
const options = {
endpoint: process.env.JAEGER_ENDPOINT,
};
const exporter = new JaegerExporter(options);
export function buildProvider(exporter: SpanExporter) {
const provider = new BasicTracerProvider();
provider.resource.attributes['service.name'] =
process.env.JAEGER_SERVICE_NAME ?? 'archive';

provider.addSpanProcessor(new BatchSpanProcessor(exporter));
trace.setGlobalTracerProvider(provider);
provider.register();
return provider;
}
Expand All @@ -25,19 +22,19 @@ export type TraceInfo = {
parentSpan: Span;
};

export function getTraceInfoFromGraphQL(parentSpan: Span | undefined) {
if (!parentSpan) return null;
const tracer = trace.getTracer('graphql');
export function createTraceInfo(parentSpan: Span) {
const tracer = getGlobalTracer();
const ctx = trace.setSpan(context.active(), parentSpan);

return { tracer, ctx, parentSpan } as TraceInfo;
}

export function getTraceInfoFromOptions(options: unknown): TraceInfo {
export function getGlobalTracer() {
return trace.getTracer('archive-node-graphql');
}

export function getTraceInfoFromOptions(options: unknown) {
if (options && typeof options === 'object' && 'traceInfo' in options) {
return options.traceInfo as TraceInfo;
}
throw new Error(
"Invalid options object: Missing or invalid 'traceInfo' property"
);
throw new Error('No trace info found');
}
120 changes: 120 additions & 0 deletions tests/__mocks__/database_mock_actions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
[
{
"action_state_value1": "1382610398438416357992097513190528030888260938367951709549566088239892891669",
"action_state_value2": "25079927036070901246064867767436987657692091363973573142121686150614948079097",
"action_state_value3": "25079927036070901246064867767436987657692091363973573142121686150614948079097",
"action_state_value4": "25079927036070901246064867767436987657692091363973573142121686150614948079097",
"action_state_value5": "25079927036070901246064867767436987657692091363973573142121686150614948079097",
"requesting_zkapp_account_identifier_id": 4091,
"block_id": 19127,
"account_identifier_id": 4091,
"zkapp_id": 700,
"account_access_id": 19127,
"state_hash": "3NKVxPBc8nZivk9bH1MPohsepuBNd5w1WEXyXuAcQxr2dWo6VsjX",
"parent_hash": "3NLjHJU8mVGLfy7dTHnWhECBGGdLhqLTYxrF8hzBrLgjP2q5Apyr",
"height": "11368",
"global_slot_since_genesis": "19283",
"global_slot_since_hard_fork": "19283",
"timestamp": "1692054601000",
"chain_status": "pending",
"ledger_hash": "jxgaJxowx33yRiqdtBtob4Zj4saXTCPvi4eWbHmk8nGHsgKzBTJ",
"distance_from_max_block_height": "279",
"last_vrf_output": "9599BEF6F6C9340BBA54A1CECBE30D19E1FC714DE6250A549BD28B554F3C0000",
"min_window_density": "32",
"sub_window_densities": [
"7",
"4",
"5",
"5",
"4",
"5",
"4",
"5",
"4",
"3",
"4"
],
"zkapp_account_update_id": 14059,
"zkapp_fee_payer_body_id": 9227,
"zkapp_account_updates_ids": [
14059
],
"authorization_kind": "Proof",
"status": "applied",
"memo": "E4Yvfh2mKHdRXNUTJoAzMsXTMftdE71sM8qTwGrRq7MdFijjGYJUg",
"hash": "5Jv5cvc3yP4LKVyV6JicxPCW12mk3ZMivTv3Rj9WBeeg2gWJQPyK",
"body_id": 14059,
"events_id": 1,
"actions_id": 137,
"id": 2,
"element_ids": [
2
],
"field": "1",
"zkapp_event_id": 137,
"zkapp_event_element_ids": [
123
],
"zkapp_event_array_id": 123
},
{
"action_state_value1": "1382610398438416357992097513190528030888260938367951709549566088239892891669",
"action_state_value2": "25079927036070901246064867767436987657692091363973573142121686150614948079097",
"action_state_value3": "25079927036070901246064867767436987657692091363973573142121686150614948079097",
"action_state_value4": "25079927036070901246064867767436987657692091363973573142121686150614948079097",
"action_state_value5": "25079927036070901246064867767436987657692091363973573142121686150614948079097",
"requesting_zkapp_account_identifier_id": 4091,
"block_id": 19127,
"account_identifier_id": 4091,
"zkapp_id": 700,
"account_access_id": 19127,
"state_hash": "3NKVxPBc8nZivk9bH1MPohsepuBNd5w1WEXyXuAcQxr2dWo6VsjX",
"parent_hash": "3NLjHJU8mVGLfy7dTHnWhECBGGdLhqLTYxrF8hzBrLgjP2q5Apyr",
"height": "11368",
"global_slot_since_genesis": "19283",
"global_slot_since_hard_fork": "19283",
"timestamp": "1692054601000",
"chain_status": "pending",
"ledger_hash": "jxgaJxowx33yRiqdtBtob4Zj4saXTCPvi4eWbHmk8nGHsgKzBTJ",
"distance_from_max_block_height": "279",
"last_vrf_output": "9599BEF6F6C9340BBA54A1CECBE30D19E1FC714DE6250A549BD28B554F3C0000",
"min_window_density": "32",
"sub_window_densities": [
"7",
"4",
"5",
"5",
"4",
"5",
"4",
"5",
"4",
"3",
"4"
],
"zkapp_account_update_id": 14060,
"zkapp_fee_payer_body_id": 9228,
"zkapp_account_updates_ids": [
14060
],
"authorization_kind": "Proof",
"status": "applied",
"memo": "E4Yvfh2mKHdRXNUTJoAzMsXTMfuS6LpqVAsogZqQ1j3MUqeo4kruY",
"hash": "5JuCVsvafc63F5vrLgoY7nGDnyRAUkhwBVNysmA7A9ZwFuUgzzCp",
"body_id": 14060,
"events_id": 1,
"actions_id": 138,
"id": 2,
"element_ids": [
2
],
"field": "1",
"zkapp_event_id": 138,
"zkapp_event_element_ids": [
123,
123,
123
],
"zkapp_event_array_id": 123
}
]
Loading

0 comments on commit 5f6403f

Please sign in to comment.