Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci/compose.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ function compose_down_all {
}

function all_weaviate_ports {
echo "8080 8081 8082 8083 8085 8086"
echo "8080 8081 8082 8083 8085 8086 8087 8088"
}
45 changes: 45 additions & 0 deletions ci/docker-compose-cluster.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
version: '3.4'
services:
weaviate-node-1:
image: semitechnologies/weaviate:preview-gql-handler-consistency-level-integration-4a12f55
restart: on-failure:0
ports:
- "8087:8080"
environment:
CONTEXTIONARY_URL: contextionary:9999
QUERY_DEFAULTS_LIMIT: 20
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
PERSISTENCE_DATA_PATH: "./weaviate-node-1"
DEFAULT_VECTORIZER_MODULE: text2vec-contextionary
ENABLE_MODULES: text2vec-contextionary
CLUSTER_GOSSIP_BIND_PORT: "7110"
CLUSTER_DATA_BIND_PORT: "7111"

weaviate-node-2:
init: true
command:
- --host
- 0.0.0.0
- --port
- '8080'
- --scheme
- http
image: semitechnologies/weaviate:preview-gql-handler-consistency-level-integration-4a12f55
ports:
- 8088:8080
- 6061:6060
restart: on-failure:0
environment:
CONTEXTIONARY_URL: contextionary:9999
LOG_LEVEL: 'debug'
QUERY_DEFAULTS_LIMIT: 20
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
PERSISTENCE_DATA_PATH: './weaviate-node-2'
DEFAULT_VECTORIZER_MODULE: text2vec-contextionary
ENABLE_MODULES: text2vec-contextionary
CLUSTER_HOSTNAME: 'node2'
CLUSTER_GOSSIP_BIND_PORT: '7112'
CLUSTER_DATA_BIND_PORT: '7113'
CLUSTER_JOIN: 'weaviate-node-1:7110'
...
38 changes: 38 additions & 0 deletions src/graphql/getter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,44 @@ test('a simple query with a group', () => {
expect(mockClient.query).toHaveBeenCalledWith(expectedQuery);
});

describe('query with consistency level', () => {
test('One', () => {
const mockClient: any = {
query: jest.fn(),
};

const expectedQuery = `{Get{Person(consistencyLevel:ONE){name}}}`;

new Getter(mockClient).withClassName('Person').withFields('name').withConsistencyLevel('ONE').do();

expect(mockClient.query).toHaveBeenCalledWith(expectedQuery);
});

test('Quorum', () => {
const mockClient: any = {
query: jest.fn(),
};

const expectedQuery = `{Get{Person(consistencyLevel:QUORUM){name}}}`;

new Getter(mockClient).withClassName('Person').withFields('name').withConsistencyLevel('QUORUM').do();

expect(mockClient.query).toHaveBeenCalledWith(expectedQuery);
});

test('All', () => {
const mockClient: any = {
query: jest.fn(),
};

const expectedQuery = `{Get{Person(consistencyLevel:ALL){name}}}`;

new Getter(mockClient).withClassName('Person').withFields('name').withConsistencyLevel('ALL').do();

expect(mockClient.query).toHaveBeenCalledWith(expectedQuery);
});
});

describe('where filters', () => {
test('a query with a valid where filter', () => {
const mockClient: any = {
Expand Down
11 changes: 11 additions & 0 deletions src/graphql/getter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Connection from '../connection';
import { CommandBase } from '../validation/commandBase';
import { WhereFilter } from '../openapi/types';
import { GenerateArgs, GraphQLGenerate } from './generate';
import { ConsistencyLevel } from '../data';

export default class GraphQLGetter extends CommandBase {
private after?: string;
Expand All @@ -31,6 +32,7 @@ export default class GraphQLGetter extends CommandBase {
private sortString?: string;
private whereString?: string;
private generateString?: string;
private consistencyLevel?: ConsistencyLevel;

constructor(client: Connection) {
super(client);
Expand Down Expand Up @@ -176,6 +178,11 @@ export default class GraphQLGetter extends CommandBase {
return this;
};

withConsistencyLevel = (level: ConsistencyLevel) => {
this.consistencyLevel = level;
return this;
};

validateIsSet = (prop: string | undefined | null, name: string, setter: string) => {
if (prop == undefined || prop == null || prop.length == 0) {
this.addError(`${name} must be set - set with ${setter}`);
Expand Down Expand Up @@ -256,6 +263,10 @@ export default class GraphQLGetter extends CommandBase {
}
}

if (this.consistencyLevel) {
args = [...args, `consistencyLevel:${this.consistencyLevel}`];
}

if (args.length > 0) {
params = `(${args.join(',')})`;
}
Expand Down
72 changes: 71 additions & 1 deletion src/graphql/journey.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1227,7 +1227,7 @@ describe('query with generative search', () => {
.withClassName('Wine')
.withFields('name review')
.withGenerate({
singlePrompt: `Describe the following as a Facebook Ad:
singlePrompt: `Describe the following as a Facebook Ad:
Tastes like a fresh ocean breeze: {review}`,
})
.do()
Expand Down Expand Up @@ -1274,6 +1274,76 @@ Tastes like a fresh ocean breeze: {review}`,
});
});

describe('query cluster with consistency level', () => {
const client = weaviate.client({
scheme: 'http',
host: 'localhost:8087',
});

it('sets up replicated class', () => {
return setupReplicated(client);
});

test('One', () => {
return client.graphql
.get()
.withClassName('Article')
.withFields('_additional { id isConsistent }')
.withConsistencyLevel('ONE')
.do()
.then((res: any) => {
expect(res.data.Get.Article.length).toBeGreaterThan(0);
res.data.Get.Article.forEach((article: any) => {
expect(article._additional.isConsistent).toBeTruthy();
});
return res;
})
.catch((e: any) => {
throw new Error(`unexpected error: ${JSON.stringify(e)}`);
});
});

test('Quorum', () => {
return client.graphql
.get()
.withClassName('Article')
.withFields('_additional { id isConsistent }')
.withConsistencyLevel('QUORUM')
.do()
.then((res: any) => {
expect(res.data.Get.Article.length).toBeGreaterThan(0);
res.data.Get.Article.forEach((article: any) => {
expect(article._additional.isConsistent).toBeTruthy();
});
})
.catch((e: any) => {
throw new Error(`unexpected error: ${JSON.stringify(e)}`);
});
});

test('All', () => {
return client.graphql
.get()
.withClassName('Article')
.withFields('_additional { id isConsistent }')
.withConsistencyLevel('ALL')
.do()
.then((res: any) => {
expect(res.data.Get.Article.length).toBeGreaterThan(0);
res.data.Get.Article.forEach((article: any) => {
expect(article._additional.isConsistent).toBeTruthy();
});
})
.catch((e: any) => {
throw new Error(`unexpected error: ${JSON.stringify(e)}`);
});
});

it('tears down cluster schema', () => {
return Promise.all([client.schema.classDeleter().withClassName('Article').do()]);
});
});

const setup = async (client: WeaviateClient) => {
const thing = {
class: 'Article',
Expand Down