From 0c10db9d5455d62e4ca6f2374d04ac5afb37ee54 Mon Sep 17 00:00:00 2001 From: Dinesh Sajwan Date: Tue, 17 Oct 2023 12:57:24 -0400 Subject: [PATCH] added rag test cases, updated summary test cases (#36) Co-authored-by: Dinesh Sajwan --- .../aws-summarization-appsync-stepfn/index.ts | 1 - .../aws-rag-appsync-stepfn-opensearch.test.ts | 180 ++++++++++++++++++ .../aws-summarization-appsync-stepfn.test.ts | 44 +++++ 3 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch.test.ts diff --git a/src/patterns/gen-ai/aws-summarization-appsync-stepfn/index.ts b/src/patterns/gen-ai/aws-summarization-appsync-stepfn/index.ts index 1b068c10..03e52302 100644 --- a/src/patterns/gen-ai/aws-summarization-appsync-stepfn/index.ts +++ b/src/patterns/gen-ai/aws-summarization-appsync-stepfn/index.ts @@ -462,7 +462,6 @@ export class SummarizationAppsyncStepfn extends Construct { ASSET_BUCKET_NAME: transformedAssetBucketName, GRAPHQL_URL: !mergeapiurl ? summarizationGraphqlApi.graphqlUrl : mergeapiurl, SUMMARY_LLM_CHAIN_TYPE: summaryChainType, - TRANSFORMERS_CACHE: '/tmp', }, }); diff --git a/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch.test.ts b/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch.test.ts new file mode 100644 index 00000000..6ba3781e --- /dev/null +++ b/test/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch/aws-rag-appsync-stepfn-opensearch.test.ts @@ -0,0 +1,180 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES + * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ +import * as cdk from 'aws-cdk-lib'; +import { Template, Match } from 'aws-cdk-lib/assertions'; +import * as cognito from 'aws-cdk-lib/aws-cognito'; +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import * as os from 'aws-cdk-lib/aws-opensearchservice'; +import * as secret from 'aws-cdk-lib/aws-secretsmanager'; +import { RagAppsyncStepfnOpensearch, RagAppsyncStepfnOpensearchProps } from '../../../../src/patterns/gen-ai/aws-rag-appsync-stepfn-opensearch'; + + +describe('RAG Appsync Stepfn Open search construct', () => { + + let ragTestTemplate: Template; + let stage = '-dev'; + let ragTestConstruct: RagAppsyncStepfnOpensearch; + const cognitoPoolId = 'us-east-1_1RVagE46n'; + + afterAll(() => { + console.log('Test completed'); + }); + + beforeAll(() => { + const ragTestStack = new cdk.Stack(undefined, undefined, { + env: { account: cdk.Aws.ACCOUNT_ID, region: cdk.Aws.REGION }, + }); + + const vpc = new ec2.Vpc(ragTestStack, 'test-vpc', + { + ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'), + enableDnsHostnames: true, + enableDnsSupport: true, + subnetConfiguration: [ + { + name: 'public', + subnetType: ec2.SubnetType.PUBLIC, + cidrMask: 24, + }, + { + name: 'private', + subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, + cidrMask: 24, + }, + ], + }, + ); + + const osDomain = os.Domain.fromDomainAttributes(ragTestStack, 'osdomain', { + domainArn: 'arn:aws:es:us-east-1:383119320704:domain/whiskeyosmanagedcluster', + domainEndpoint: 'https://vpc-whiskeyosmanagedcluster-4pkv5sj6vhoz5lrxn35wfidrie.us-east-1.es.amazonaws.com', + }); + + const osSecret = secret.Secret.fromSecretNameV2(ragTestStack, 'ossecret', 'OSSecret4A7B7484-NJb2Ppu2AmvJ'); + + const userPoolLoaded = cognito.UserPool.fromUserPoolId(ragTestStack, 'testUserPool', cognitoPoolId); + + const ragTestprops: RagAppsyncStepfnOpensearchProps = { + existingVpc: vpc, + existinOpensearchDomain: osDomain, + openSearchIndexName: 'demoindex', + openSearchSecret: osSecret, + cognitoUserPool: userPoolLoaded, + }; + + ragTestConstruct = new RagAppsyncStepfnOpensearch(ragTestStack, 'test', ragTestprops); + ragTestTemplate = Template.fromStack(ragTestStack); + }); + + test('Lambda properties', () => { + ragTestTemplate.hasResourceProperties('AWS::Lambda::Function', { + PackageType: 'Image', + FunctionName: 'embeddings_job_docker'+stage, + Environment: { + Variables: { + GRAPHQL_URL: { 'Fn::GetAtt': [Match.stringLikeRegexp('testingestionGraphqlApi'), 'GraphQLUrl'] }, + INPUT_BUCKET: { Ref: Match.stringLikeRegexp('testinputAssetsBucket') }, + OPENSEARCH_DOMAIN_ENDPOINT: Match.stringLikeRegexp('vpc-whiskeyosmanagedcluster-'), + OPENSEARCH_INDEX: 'demoindex', + OPENSEARCH_SECRET_ID: Match.stringLikeRegexp('OSSecret'), + OUTPUT_BUCKET: { Ref: Match.stringLikeRegexp('testprocessedAssetsBucketdev') }, + }, + }, + }); + ragTestTemplate.hasResourceProperties('AWS::Lambda::Function', { + PackageType: 'Image', + FunctionName: 's3_file_transformer_docker'+stage, + Environment: { + Variables: { + GRAPHQL_URL: { 'Fn::GetAtt': [Match.stringLikeRegexp('testingestionGraphqlApi'), 'GraphQLUrl'] }, + INPUT_BUCKET: { Ref: Match.stringLikeRegexp('testinputAssetsBucket') }, + OUTPUT_BUCKET: { Ref: Match.stringLikeRegexp('testprocessedAssetsBucket') }, + }, + }, + }); + ragTestTemplate.hasResourceProperties('AWS::Lambda::Function', { + PackageType: 'Image', + FunctionName: 'ingestion_input_validation_docker'+stage, + Environment: { + Variables: + { + GRAPHQL_URL: + { + 'Fn::GetAtt': + [Match.stringLikeRegexp('testingestionGraphqlApi'), + 'GraphQLUrl'], + }, + }, + }, + }); + + }); + + test('Lambda function count', () => { + ragTestTemplate.resourceCountIs('AWS::Lambda::Function', 4); + }); + + test('Appsync Merge Graphql Properties', () => { + ragTestTemplate.hasResourceProperties('AWS::AppSync::GraphQLApi', { + UserPoolConfig: {}, + AuthenticationType: 'AMAZON_COGNITO_USER_POOLS', + }); + }); + + test('Appsync Graphql Count', () => { + ragTestTemplate.resourceCountIs('AWS::AppSync::GraphQLApi', 1); + }); + + test('Event Bus rule Target', () => { + ragTestTemplate.hasResourceProperties('AWS::Events::Rule', + Match.objectEquals + ({ + Description: 'Rule to trigger ingestion function', + EventBusName: { Ref: Match.stringLikeRegexp('testingestionEventBus') }, + EventPattern: { source: ['ingestion'] }, + State: 'ENABLED', + Targets: + [{ + Arn: + { Ref: Match.stringLikeRegexp('estIngestionStateMachine') }, + Id: 'Target0', + RoleArn: { 'Fn::GetAtt': [Match.stringLikeRegexp('testIngestionStateMachineEvent'), 'Arn'] }, + + }], + }, + )); + }); + + test('S3 Bucket Properties', () => { + ragTestTemplate.hasResourceProperties('AWS::S3::Bucket', { + BucketEncryption: { ServerSideEncryptionConfiguration: [{ ServerSideEncryptionByDefault: { SSEAlgorithm: 'AES256' } }] }, + }); + expect(ragTestConstruct.s3InputAssetsBucket).not.toBeNull; + expect(ragTestConstruct.s3ProcessedAssetsBucket).not.toBeNull; + }); + + test('S3 Bucket Count', () => { + ragTestTemplate.resourceCountIs('AWS::S3::Bucket', 2); + }); + + test('Step function count', () => { + ragTestTemplate.resourceCountIs('AWS::StepFunctions::StateMachine', 1); + }); + + test('Step function defined ', () => { + expect(ragTestConstruct.stateMachine).toBeDefined; + expect(ragTestConstruct.stateMachine).not.toBeNull; + }); + + +}); \ No newline at end of file diff --git a/test/patterns/gen-ai/aws-summarization-appsync-stepfn/aws-summarization-appsync-stepfn.test.ts b/test/patterns/gen-ai/aws-summarization-appsync-stepfn/aws-summarization-appsync-stepfn.test.ts index d48bc9c0..90519ca2 100644 --- a/test/patterns/gen-ai/aws-summarization-appsync-stepfn/aws-summarization-appsync-stepfn.test.ts +++ b/test/patterns/gen-ai/aws-summarization-appsync-stepfn/aws-summarization-appsync-stepfn.test.ts @@ -107,14 +107,54 @@ describe('Summarization Appsync Stepfn construct', () => { summarizationTestTemplate.hasResourceProperties('AWS::Lambda::Function', { PackageType: 'Image', FunctionName: 'summary_input_validator-dev', + Environment: { + Variables: { + GRAPHQL_URL: { + 'Fn::GetAtt': [ + Match.stringLikeRegexp('summaryMergedapi'), + 'GraphQLUrl', + ], + }, + }, + }, + }); summarizationTestTemplate.hasResourceProperties('AWS::Lambda::Function', { PackageType: 'Image', FunctionName: 'summary_document_reader-dev', + Environment: { + Variables: { + GRAPHQL_URL: { + 'Fn::GetAtt': [ + Match.stringLikeRegexp('summaryMergedapi'), + 'GraphQLUrl', + ], + }, + INPUT_ASSET_BUCKET: { Ref: Match.stringLikeRegexp('testinputAssetsBucketdev') }, + IS_FILE_TRANSFORMED: 'false', + REDIS_HOST: { 'Fn::GetAtt': [Match.stringLikeRegexp('testredisCluster'), 'RedisEndpoint.Address'] }, + REDIS_PORT: { 'Fn::GetAtt': [Match.stringLikeRegexp('testredisCluster'), 'RedisEndpoint.Port'] }, + TRANSFORMED_ASSET_BUCKET: { Ref: Match.stringLikeRegexp('testprocessedAssetsBucket') }, + }, + }, }); summarizationTestTemplate.hasResourceProperties('AWS::Lambda::Function', { PackageType: 'Image', FunctionName: 'summary_generator-dev', + Environment: { + Variables: { + ASSET_BUCKET_NAME: { Ref: 'testprocessedAssetsBucketdevF293824A' }, + GRAPHQL_URL: { + 'Fn::GetAtt': [ + Match.stringLikeRegexp('summaryMergedapi'), + 'GraphQLUrl', + ], + }, + REDIS_HOST: { 'Fn::GetAtt': [Match.stringLikeRegexp('testredisCluster'), 'RedisEndpoint.Address'] }, + REDIS_PORT: { 'Fn::GetAtt': [Match.stringLikeRegexp('testredisCluster'), 'RedisEndpoint.Port'] }, + SUMMARY_LLM_CHAIN_TYPE: 'stuff', + }, + }, }); }); @@ -179,6 +219,10 @@ describe('Summarization Appsync Stepfn construct', () => { summarizationTestTemplate.resourceCountIs('AWS::StepFunctions::StateMachine', 1); }); + test('S3 Bucket Count', () => { + summarizationTestTemplate.resourceCountIs('AWS::S3::Bucket', 2); + expect(summarizationTestConstruct.inputAssetBucket).not.toBeNull; + }); test('Step function defined ', () => { expect(summarizationTestConstruct.stateMachine).toBeDefined;