Skip to content

Commit

Permalink
Merge pull request #398 from everett980/fetch-ddg-action-and-reducer
Browse files Browse the repository at this point in the history
Fetch ddg action and reducer
  • Loading branch information
everett980 authored Jul 2, 2019
2 parents d507832 + ef15710 commit fdea0f7
Show file tree
Hide file tree
Showing 24 changed files with 1,807 additions and 185 deletions.
1 change: 1 addition & 0 deletions packages/jaeger-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"jest": {
"collectCoverageFrom": [
"src/**/*.js",
"!src/components/DeepDependencyGraph/Header.tsx",
"!src/setup*.js",
"!src/utils/DraggableManager/demo/*.js",
"!src/utils/test/**/*.js",
Expand Down
48 changes: 48 additions & 0 deletions packages/jaeger-ui/src/actions/deep-dependency-graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import _identity from 'lodash/identity';
import { createActions } from 'redux-actions';

import {
TDdgAddViewModifierPayload,
TDdgClearViewModifiersFromIndicesPayload,
TDdgRemoveViewModifierFromIndicesPayload,
TDdgRemoveViewModifierPayload,
TDdgViewModifierRemovalPayload,
} from '../model/ddg/types';
import generateActionTypes from '../utils/generate-action-types';

export const actionTypes = generateActionTypes('@jaeger-ui/DEEP-DEPENDENCY-GRAPH', [
'ADD_VIEW_MODIFIER',
'CLEAR_VIEW_MODIFIERS_FROM_INDICES',
'REMOVE_VIEW_MODIFIER',
'REMOVE_VIEW_MODIFIER_FROM_INDICES',
]);

const addViewModifier: (kwarg: TDdgAddViewModifierPayload) => TDdgAddViewModifierPayload = _identity;
const clearViewModifiersFromIndices: (
kwarg: TDdgClearViewModifiersFromIndicesPayload
) => TDdgClearViewModifiersFromIndicesPayload = _identity;
const removeViewModifier: (kwarg: TDdgRemoveViewModifierPayload) => TDdgRemoveViewModifierPayload = _identity;
const removeViewModifierFromIndices: (
kwarg: TDdgRemoveViewModifierFromIndicesPayload
) => TDdgRemoveViewModifierFromIndicesPayload = _identity;

export const actions = createActions<TDdgAddViewModifierPayload | TDdgViewModifierRemovalPayload>({
[actionTypes.ADD_VIEW_MODIFIER]: addViewModifier,
[actionTypes.CLEAR_VIEW_MODIFIERS_FROM_INDICES]: clearViewModifiersFromIndices,
[actionTypes.REMOVE_VIEW_MODIFIER]: removeViewModifier,
[actionTypes.REMOVE_VIEW_MODIFIER_FROM_INDICES]: removeViewModifierFromIndices,
});
22 changes: 22 additions & 0 deletions packages/jaeger-ui/src/actions/jaeger-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import { createAction } from 'redux-actions';
import JaegerAPI from '../api/jaeger';

import * as paths from '../model/ddg/sample-paths.test.resources';

export const fetchTrace = createAction(
'@JAEGER_API/FETCH_TRACE',
id => JaegerAPI.fetchTrace(id),
Expand Down Expand Up @@ -47,6 +49,26 @@ export const fetchServiceOperations = createAction(
serviceName => ({ serviceName })
);

function tempTestFetch() {
let resolve;
const promise = new Promise(res => {
resolve = res;
});
setTimeout(() => {
/* istanbul ignore next */
resolve([paths.simplePath, paths.almostDoubleFocalPath]);
}, 1000);
return promise;
}

export const fetchDeepDependencyGraph = createAction(
'@JAEGER_API/FETCH_DEEP_DEPENDENCY_GRAPH',
// Temporary mock used until backend is available, TODO revert & re-enable test
// query => JaegerAPI.fetchDeepDependencyGraph(query),
tempTestFetch,
query => ({ query })
);

export const fetchDependencies = createAction('@JAEGER_API/FETCH_DEPENDENCIES', () =>
JaegerAPI.fetchDependencies()
);
198 changes: 113 additions & 85 deletions packages/jaeger-ui/src/actions/jaeger-api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,90 +27,118 @@ import isPromise from 'is-promise';
import * as jaegerApiActions from './jaeger-api';
import JaegerAPI from '../api/jaeger';

it('@JAEGER_API/FETCH_TRACE should fetch the trace by id', () => {
const api = JaegerAPI;
describe('actions/jaeger-api', () => {
const query = { param: 'value' };
const id = 'my-trace-id';
const mock = sinon.mock(api);

mock.expects('fetchTrace').withExactArgs(id);
jaegerApiActions.fetchTrace(id);
expect(() => mock.verify()).not.toThrow();

mock.restore();
});

it('@JAEGER_API/FETCH_TRACE should return the promise', () => {
const api = JaegerAPI;
const id = 'my-trace-id';
const mock = sinon.mock(api);

const { payload } = jaegerApiActions.fetchTrace(id);
expect(isPromise(payload)).toBeTruthy();

mock.restore();
});

it('@JAEGER_API/FETCH_TRACE should attach the id as meta', () => {
const api = JaegerAPI;
const id = 'my-trace-id';
const mock = sinon.mock(api);

const { meta } = jaegerApiActions.fetchTrace(id);
expect(meta.id).toBe(id);

mock.restore();
});

it('@JAEGER_API/SEARCH_TRACES should fetch the trace by id', () => {
const api = JaegerAPI;
const query = { service: 's', limit: 1 };
const mock = sinon.mock(api);

mock.expects('searchTraces').withExactArgs(query);
jaegerApiActions.searchTraces(query);
expect(() => mock.verify()).not.toThrow();

mock.restore();
});

it('@JAEGER_API/SEARCH_TRACES should return the promise', () => {
const api = JaegerAPI;
const query = { myQuery: 'whatever' };
const mock = sinon.mock(api);

const { payload } = jaegerApiActions.searchTraces(query);
expect(isPromise(payload)).toBeTruthy();

mock.restore();
});

it('@JAEGER_API/SEARCH_TRACES should attach the query as meta', () => {
const api = JaegerAPI;
const query = { myQuery: 'whatever' };
const mock = sinon.mock(api);

const { meta } = jaegerApiActions.searchTraces(query);
expect(meta.query).toEqual(query);

mock.restore();
});

it('@JAEGER_API/FETCH_SERVICES should return a promise', () => {
const api = JaegerAPI;
const mock = sinon.mock(api);
const { payload } = jaegerApiActions.fetchServices();
expect(isPromise(payload)).toBeTruthy();
mock.restore();
});

it('@JAEGER_API/FETCH_SERVICE_OPERATIONS should call the JaegerAPI', () => {
const api = JaegerAPI;
const mock = sinon.mock(api);
const called = mock
.expects('fetchServiceOperations')
.once()
.withExactArgs('service');
jaegerApiActions.fetchServiceOperations('service');
expect(called.verify()).toBeTruthy();
mock.restore();
const ids = [id, id];
let mock;

beforeEach(() => {
mock = sinon.mock(JaegerAPI);
});

afterEach(() => {
mock.restore();
});

it('@JAEGER_API/FETCH_TRACE should fetch the trace by id', () => {
mock.expects('fetchTrace').withExactArgs(id);
jaegerApiActions.fetchTrace(id);
expect(() => mock.verify()).not.toThrow();
});

it('@JAEGER_API/FETCH_TRACE should return the promise', () => {
const { payload } = jaegerApiActions.fetchTrace(id);
expect(isPromise(payload)).toBeTruthy();
});

it('@JAEGER_API/FETCH_TRACE should attach the id as meta', () => {
const { meta } = jaegerApiActions.fetchTrace(id);
expect(meta.id).toBe(id);
});

it('@JAEGER_API/FETCH_MULTIPLE_TRACES should fetch traces by ids', () => {
mock.expects('searchTraces').withExactArgs(sinon.match.has('traceID', ids));
jaegerApiActions.fetchMultipleTraces(ids);
expect(() => mock.verify()).not.toThrow();
});

it('@JAEGER_API/FETCH_MULTIPLE_TRACES should return the promise', () => {
const { payload } = jaegerApiActions.fetchMultipleTraces(ids);
expect(isPromise(payload)).toBeTruthy();
});

it('@JAEGER_API/FETCH_MULTIPLE_TRACES should attach the ids as meta', () => {
const { meta } = jaegerApiActions.fetchMultipleTraces(ids);
expect(meta.ids).toBe(ids);
});

it('@JAEGER_API/ARCHIVE_TRACE should archive the trace by id', () => {
mock.expects('archiveTrace').withExactArgs(id);
jaegerApiActions.archiveTrace(id);
expect(() => mock.verify()).not.toThrow();
});

it('@JAEGER_API/ARCHIVE_TRACE should return the promise', () => {
const { payload } = jaegerApiActions.archiveTrace(id);
expect(isPromise(payload)).toBeTruthy();
});

it('@JAEGER_API/ARCHIVE_TRACE should attach the id as meta', () => {
const { meta } = jaegerApiActions.archiveTrace(id);
expect(meta.id).toBe(id);
});

it('@JAEGER_API/SEARCH_TRACES should fetch the trace by id', () => {
mock.expects('searchTraces').withExactArgs(query);
jaegerApiActions.searchTraces(query);
expect(() => mock.verify()).not.toThrow();
});

it('@JAEGER_API/SEARCH_TRACES should return the promise', () => {
const { payload } = jaegerApiActions.searchTraces(query);
expect(isPromise(payload)).toBeTruthy();
});

it('@JAEGER_API/SEARCH_TRACES should attach the query as meta', () => {
const { meta } = jaegerApiActions.searchTraces(query);
expect(meta.query).toEqual(query);
});

it('@JAEGER_API/FETCH_SERVICES should return a promise', () => {
const { payload } = jaegerApiActions.fetchServices();
expect(isPromise(payload)).toBeTruthy();
});

it('@JAEGER_API/FETCH_SERVICE_OPERATIONS should call the JaegerAPI', () => {
const called = mock
.expects('fetchServiceOperations')
.once()
.withExactArgs('service');
jaegerApiActions.fetchServiceOperations('service');
expect(called.verify()).toBeTruthy();
});

// Temporary mock used until backend is available, TODO revert & re-enable test
xit('@JAEGER_API/FETCH_DEEP_DEPENDENCY_GRAPH should fetch the graph by params', () => {
mock.expects('fetchDeepDependencyGraph').withExactArgs(query);
jaegerApiActions.fetchDeepDependencyGraph(query);
expect(() => mock.verify()).not.toThrow();
});

it('@JAEGER_API/FETCH_DEEP_DEPENDENCY_GRAPH should return the promise', () => {
const { payload } = jaegerApiActions.fetchDeepDependencyGraph(query);
expect(isPromise(payload)).toBeTruthy();
});

it('@JAEGER_API/FETCH_DEEP_DEPENDENCY_GRAPH should attach the query as meta', () => {
const { meta } = jaegerApiActions.fetchDeepDependencyGraph(query);
expect(meta.query).toEqual(query);
});

it('@JAEGER_API/FETCH_DEPENDENCIES should call the JaegerAPI', () => {
const called = mock.expects('fetchDependencies').once();
jaegerApiActions.fetchDependencies();
expect(called.verify()).toBeTruthy();
});
});
21 changes: 12 additions & 9 deletions packages/jaeger-ui/src/api/jaeger.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,26 @@ export const DEFAULT_DEPENDENCY_LOOKBACK = moment.duration(1, 'weeks').asMillise

const JaegerAPI = {
apiRoot: DEFAULT_API_ROOT,
fetchTrace(id) {
return getJSON(`${this.apiRoot}traces/${id}`);
},
archiveTrace(id) {
return getJSON(`${this.apiRoot}archive/${id}`, { method: 'POST' });
},
searchTraces(query) {
return getJSON(`${this.apiRoot}traces`, { query });
fetchDeepDependencyGraph(query) {
return getJSON(`${this.apiRoot}deep-dependency-graph`, { query });
},
fetchServices() {
return getJSON(`${this.apiRoot}services`);
fetchDependencies(endTs = new Date().getTime(), lookback = DEFAULT_DEPENDENCY_LOOKBACK) {
return getJSON(`${this.apiRoot}dependencies`, { query: { endTs, lookback } });
},
fetchServiceOperations(serviceName) {
return getJSON(`${this.apiRoot}services/${encodeURIComponent(serviceName)}/operations`);
},
fetchDependencies(endTs = new Date().getTime(), lookback = DEFAULT_DEPENDENCY_LOOKBACK) {
return getJSON(`${this.apiRoot}dependencies`, { query: { endTs, lookback } });
fetchServices() {
return getJSON(`${this.apiRoot}services`);
},
fetchTrace(id) {
return getJSON(`${this.apiRoot}traces/${id}`);
},
searchTraces(query) {
return getJSON(`${this.apiRoot}traces`, { query });
},
};

Expand Down
Loading

0 comments on commit fdea0f7

Please sign in to comment.