Skip to content

Commit 47f7548

Browse files
authored
test: Ensures that all storage providers are tested on CI (#740)
To avoid using time supporting things now and in the future that aren't being used, we've made the following breaking changes. Note that the Google Cloud Storage package has also been upgraded which helped resolve some flakiness with the tests. BREAKING CHANGE: No longer supporting `redis-sentinel` due to testing complications and a lack of return on the investment into maintenance. You can use [HAProxy](https://www.haproxy.com/blog/haproxy-advanced-redis-health-check/) as an alternative. You may also consider using Azure Cache, AWS ElastiCache, or Google Cloud Memorystore. Ensure that `EVENTS_REPO=sentinel` is no longer used in your .env file. BREAKING CHANGE: No longer supporting `AUTH_REPO=fetch`. This was a legacy auth repo from days when we were transitioning from PHP to Node. Use `AUTH_REPO=mongo` instead.
1 parent e5fdbcc commit 47f7548

File tree

80 files changed

+622
-673
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+622
-673
lines changed

.circleci/config.yml

Lines changed: 175 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
version: 2.1
2+
23
machine:
34
services:
45
- docker
@@ -10,20 +11,8 @@ jobs:
1011
auth:
1112
username: $DOCKERHUB_USERNAME
1213
password: $DOCKERHUB_PASSWORD
13-
- image: mongo:3.7.9@sha256:736eec20a17eafaa988d299902fcaab521cb0ca56af4400f782576afc878d6bc
14-
auth:
15-
username: $DOCKERHUB_USERNAME
16-
password: $DOCKERHUB_PASSWORD
17-
- image: redis:3.2.12@sha256:562e944371527d6e11d396fe43fde17c30e28c25c23561b2322db3905cbc71dd
18-
auth:
19-
username: $DOCKERHUB_USERNAME
20-
password: $DOCKERHUB_PASSWORD
2114
environment:
22-
- DOCKER_REPO_SLUG: learninglocker/xapi-service
23-
- DOCKER_EMAIL: [email protected]
2415
- NPM_CONFIG_LOGLEVEL: warn
25-
- WINSTON_CONSOLE_LEVEL: none
26-
- EXPRESS_PORT: 1337
2716
working_directory: ~/repo
2817
steps:
2918
- checkout
@@ -43,16 +32,161 @@ jobs:
4332
- run:
4433
name: Linting Code
4534
command: yarn lint-ci
35+
- save_cache:
36+
paths:
37+
- dist
38+
key: dist-{{ .Branch }}-{{ .Revision }}
39+
test-local:
40+
docker:
41+
- image: node:12
42+
auth:
43+
username: $DOCKERHUB_USERNAME
44+
password: $DOCKERHUB_PASSWORD
45+
- image: mongo:3.7.9@sha256:736eec20a17eafaa988d299902fcaab521cb0ca56af4400f782576afc878d6bc
46+
auth:
47+
username: $DOCKERHUB_USERNAME
48+
password: $DOCKERHUB_PASSWORD
49+
- image: redis:3.2.12@sha256:562e944371527d6e11d396fe43fde17c30e28c25c23561b2322db3905cbc71dd
50+
auth:
51+
username: $DOCKERHUB_USERNAME
52+
password: $DOCKERHUB_PASSWORD
53+
environment:
54+
- WINSTON_CONSOLE_LEVEL: none
55+
- EXPRESS_PORT: 1337
56+
working_directory: ~/repo
57+
steps:
58+
- checkout
59+
- restore_cache:
60+
keys:
61+
- v1-dependencies-{{ checksum "yarn.lock" }}
62+
- restore_cache:
63+
keys:
64+
- dist-{{ .Branch }}-{{ .Revision }}
4665
- run:
4766
name: Mocha Tests
48-
command: yarn cover-ci
67+
command: yarn cover-local
4968
- run:
5069
name: Conformance Tests
5170
command: sh test.sh
52-
- save_cache:
53-
paths:
54-
- dist
55-
key: dist-{{ .Branch }}-{{ .Revision }}
71+
- run: yarn codecov
72+
test-s3:
73+
docker:
74+
- image: node:12
75+
auth:
76+
username: $DOCKERHUB_USERNAME
77+
password: $DOCKERHUB_PASSWORD
78+
- image: mongo:3.7.9@sha256:736eec20a17eafaa988d299902fcaab521cb0ca56af4400f782576afc878d6bc
79+
auth:
80+
username: $DOCKERHUB_USERNAME
81+
password: $DOCKERHUB_PASSWORD
82+
- image: redis:3.2.12@sha256:562e944371527d6e11d396fe43fde17c30e28c25c23561b2322db3905cbc71dd
83+
auth:
84+
username: $DOCKERHUB_USERNAME
85+
password: $DOCKERHUB_PASSWORD
86+
environment:
87+
- WINSTON_CONSOLE_LEVEL: none
88+
- EXPRESS_PORT: 1337
89+
- STORAGE_REPO: s3
90+
working_directory: ~/repo
91+
steps:
92+
- checkout
93+
- restore_cache:
94+
keys:
95+
- v1-dependencies-{{ checksum "yarn.lock" }}
96+
- restore_cache:
97+
keys:
98+
- dist-{{ .Branch }}-{{ .Revision }}
99+
- run:
100+
name: Setup S3 Env
101+
command: |
102+
echo 'export SUB_FOLDER_ACTIVITIES=circleci/$CIRCLE_BUILD_NUM' >> $BASH_ENV
103+
echo 'export SUB_FOLDER_AGENTS=circleci/$CIRCLE_BUILD_NUM' >> $BASH_ENV
104+
echo 'export SUB_FOLDER_STATE=circleci/$CIRCLE_BUILD_NUM' >> $BASH_ENV
105+
echo 'export SUB_FOLDER_STATEMENTS=circleci/$CIRCLE_BUILD_NUM' >> $BASH_ENV
106+
source $BASH_ENV
107+
- run:
108+
name: Mocha Tests
109+
command: yarn cover-s3
110+
- run:
111+
name: Conformance Tests
112+
command: sh test.sh
113+
- run: yarn codecov
114+
test-azure:
115+
docker:
116+
- image: node:12
117+
auth:
118+
username: $DOCKERHUB_USERNAME
119+
password: $DOCKERHUB_PASSWORD
120+
- image: mongo:3.7.9@sha256:736eec20a17eafaa988d299902fcaab521cb0ca56af4400f782576afc878d6bc
121+
auth:
122+
username: $DOCKERHUB_USERNAME
123+
password: $DOCKERHUB_PASSWORD
124+
- image: redis:3.2.12@sha256:562e944371527d6e11d396fe43fde17c30e28c25c23561b2322db3905cbc71dd
125+
auth:
126+
username: $DOCKERHUB_USERNAME
127+
password: $DOCKERHUB_PASSWORD
128+
environment:
129+
- WINSTON_CONSOLE_LEVEL: none
130+
- EXPRESS_PORT: 1337
131+
- STORAGE_REPO: azure
132+
working_directory: ~/repo
133+
steps:
134+
- checkout
135+
- restore_cache:
136+
keys:
137+
- v1-dependencies-{{ checksum "yarn.lock" }}
138+
- restore_cache:
139+
keys:
140+
- dist-{{ .Branch }}-{{ .Revision }}
141+
- run:
142+
name: Setup Azure Env
143+
command: |
144+
echo 'export FS_AZURE_CONTAINER_SUBFOLDER=circleci/$CIRCLE_BUILD_NUM' >> $BASH_ENV
145+
source $BASH_ENV
146+
- run:
147+
name: Mocha Tests
148+
command: yarn cover-azure
149+
- run:
150+
name: Conformance Tests
151+
command: sh test.sh
152+
- run: yarn codecov
153+
test-google:
154+
docker:
155+
- image: node:12
156+
auth:
157+
username: $DOCKERHUB_USERNAME
158+
password: $DOCKERHUB_PASSWORD
159+
- image: mongo:3.7.9@sha256:736eec20a17eafaa988d299902fcaab521cb0ca56af4400f782576afc878d6bc
160+
auth:
161+
username: $DOCKERHUB_USERNAME
162+
password: $DOCKERHUB_PASSWORD
163+
- image: redis:3.2.12@sha256:562e944371527d6e11d396fe43fde17c30e28c25c23561b2322db3905cbc71dd
164+
auth:
165+
username: $DOCKERHUB_USERNAME
166+
password: $DOCKERHUB_PASSWORD
167+
environment:
168+
- WINSTON_CONSOLE_LEVEL: none
169+
- EXPRESS_PORT: 1337
170+
- STORAGE_REPO: google
171+
working_directory: ~/repo
172+
steps:
173+
- checkout
174+
- restore_cache:
175+
keys:
176+
- v1-dependencies-{{ checksum "yarn.lock" }}
177+
- restore_cache:
178+
keys:
179+
- dist-{{ .Branch }}-{{ .Revision }}
180+
- run:
181+
name: Setup Google Key File
182+
command: echo ${GCLOUD_SERVICE_KEY} > ./google.keyfile.json
183+
- run:
184+
name: Mocha Tests
185+
command: yarn cover-google
186+
- run:
187+
name: Conformance Tests
188+
command: sh test.sh
189+
- run: yarn codecov
56190
release:
57191
docker:
58192
- image: node:12
@@ -61,7 +195,6 @@ jobs:
61195
password: $DOCKERHUB_PASSWORD
62196
environment:
63197
- DOCKER_REPO_SLUG: learninglocker/xapi-service
64-
- DOCKER_EMAIL: [email protected]
65198
working_directory: ~/repo
66199
steps:
67200
- checkout
@@ -104,11 +237,34 @@ workflows:
104237
- build:
105238
context:
106239
- docker-hub-creds
107-
- release:
240+
- test-local:
108241
context:
109242
- docker-hub-creds
110243
requires:
111244
- build
245+
- test-s3:
246+
context:
247+
- docker-hub-creds
248+
requires:
249+
- test-local
250+
- test-azure:
251+
context:
252+
- docker-hub-creds
253+
requires:
254+
- test-local
255+
- test-google:
256+
context:
257+
- docker-hub-creds
258+
requires:
259+
- test-local
260+
- release:
261+
context:
262+
- docker-hub-creds
263+
requires:
264+
- test-local
265+
- test-s3
266+
- test-azure
267+
- test-google
112268
filters:
113269
branches:
114270
ignore:

package.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,29 @@
1818
"start": "node dist/server.js",
1919
"start:dev": "nodemon",
2020
"build": "tsc",
21-
"test": "SERVICE_AWAIT_UPDATES=true AUTH_REPO=test mocha $(find dist -name '*.test.js') --timeout 6000 --exit",
22-
"test-s3": "MODELS_REPO=mongo STORAGE_REPO=s3 npm run test",
23-
"test-google": "MODELS_REPO=mongo STORAGE_REPO=google npm run test",
24-
"test-azure": "MODELS_REPO=mongo STORAGE_REPO=azure npm run test",
25-
"test-mongo": "MODELS_REPO=mongo STORAGE_REPO=local npm run test",
26-
"test-sentinel": "MODELS_REPO=mongo STORAGE_REPO=local EVENTS_REPO=sentinel npm run test",
27-
"test-ci": "npm run test-mongo",
28-
"test-all": "npm run test-ci && npm run test-s3 && npm run test-google && npm run test-sentinel && npm run test-azure",
29-
"cover-ci": "nyc --lines 100 --check-coverage --exclude '(dist/**/*google*|dist/**/*azure*|dist/**/*s3*|dist/**/*fetch*|dist/**/*fake*|dist/config.js|dist/**/factory.js|dist/**/facade.js|dist/**/connectToSentinel.js)' npm run test-ci",
30-
"cover-all": "nyc --lines 100 --check-coverage --exclude '(dist/**/*fetch*|dist/**/*fake*|dist/config.js|dist/**/factory.js|dist/**/facade.js)' npm run test-all",
21+
"test": "SERVICE_AWAIT_UPDATES=true AUTH_REPO=test mocha $(find dist -name '*.test.js') --timeout 20000 --exit --bail",
22+
"test-local": "STORAGE_REPO=local nyc npm run test",
23+
"test-s3": "STORAGE_REPO=s3 npm run test",
24+
"test-azure": "STORAGE_REPO=azure npm run test",
25+
"test-google": "STORAGE_REPO=google npm run test",
26+
"cover-local": "nyc npm run test-local",
27+
"cover-s3": "nyc npm run test-s3",
28+
"cover-azure": "nyc npm run test-azure",
29+
"cover-google": "nyc npm run test-google",
3130
"clean": "rm -rf dist",
3231
"lint": "eslint --cache --quiet --fix src",
3332
"lint-ci": "eslint --quiet src",
3433
"duplication": "jscpd",
35-
"semantic-release": "ht2-release-public-circleci-app"
34+
"semantic-release": "ht2-release-public-circleci-app",
35+
"codecov": "nyc report --reporter=text-lcov > coverage.lcov && codecov"
3636
},
3737
"engines": {
3838
"node": ">6.0.0",
3939
"npm": ">3.0.0"
4040
},
4141
"dependencies": {
4242
"@azure/storage-blob": "^10.3.0",
43-
"@google-cloud/storage": "^1.5.2",
43+
"@google-cloud/storage": "^5.8.1",
4444
"@learninglocker/xapi-validation": "^2.1.10",
4545
"accept-language-parser": "^1.5.0",
4646
"atob": "^2.0.3",
@@ -80,7 +80,6 @@
8080
"@types/dotenv": "6.1.1",
8181
"@types/express": "4.17.11",
8282
"@types/fs-extra": "8.1.1",
83-
"@types/google-cloud__storage": "1.7.0",
8483
"@types/ioredis": "3.2.24",
8584
"@types/jsonwebtoken": "8.5.0",
8685
"@types/lodash": "4.14.168",
@@ -95,6 +94,7 @@
9594
"@types/supertest": "2.0.10",
9695
"@types/uuid": "8.3.0",
9796
"@types/winston": "2.4.4",
97+
"codecov": "3.8.1",
9898
"@typescript-eslint/eslint-plugin": "4.17.0",
9999
"@typescript-eslint/parser": "4.17.0",
100100
"colors": "1.4.0",

readme.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
66
[![Join the chat at https://gitter.im/LearningLocker/learninglocker](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/LearningLocker/learninglocker?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
77

8-
*Learning Locker is a trademark of [Learning Pool](http://learningpool.com)*
8+
_Learning Locker is a trademark of [Learning Pool](http://learningpool.com)_
99

1010
### Development: Installation
1111

@@ -26,23 +26,25 @@ Do not use sudo for any of these installations or commands. If you're working on
2626

2727
Before you follow these instructions you may want to exit your `yarn start` command above with Ctrl + C. This ensures that the running app doesn't interfere with your testing by using Mongo and Redis.
2828

29-
1. Install dependencies with `yarn`.
29+
1. Install dependencies with `yarn --frozen-lockfile`.
3030
1. Start Mongo and Redis with `docker-compose up -d`. If you've followed the [Enterprise setup instructions](https://github.com/LearningLocker/enterprise/blob/master/README.md) already you won't need to do this.
3131
1. Lint the code with `yarn lint`.
3232
1. Build the code with `yarn build`.
33-
1. Test the code with `yarn cover-ci`.
33+
1. Test the code with `yarn test-local`.
3434
1. Stop the Mongo and Redis with `docker-compose down`. Use `-v` at the end to delete data.
3535

3636
### Production: Installation
37+
3738
To install all of Learning Locker, see the [installation documentation](http://docs.learninglocker.net/guides-installing/). To install just the xAPI service, you can follow the instructions below.
3839

3940
1. Clone the repository with `git clone [email protected]:LearningLocker/xapi-service.git`.
4041
1. Switch to the repository directory with `cd xapi-service`.
41-
1. Install dependencies with `yarn`.
42+
1. Install dependencies with `yarn --frozen-lockfile`.
4243
1. Build the code with `yarn build`.
4344
1. Start the server with `yarn start`.
4445

4546
### Docker
47+
4648
You can use the steps below to install and run the xAPI service.
4749

4850
- Create a ".env" file using the ".env.example" file in this Github repository.

src/apps/AppConfig.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ export default interface AppConfig {
4545
readonly prefix: string;
4646
readonly client: () => Promise<Redis>;
4747
};
48-
readonly sentinel: {
49-
readonly prefix: string;
50-
readonly client: () => Promise<Redis>;
51-
};
5248
};
5349
readonly service: {
5450
readonly statements: {

src/apps/activities/azureStorageRepo/clearRepo.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@ export default (config: Config) => {
1010
// eslint-disable-next-line functional/no-let
1111
let marker;
1212
// eslint-disable-next-line functional/no-loop-statement
13-
do {
13+
while (marker !== '') {
1414
const listBlobsResponse: Models.ContainerListBlobFlatSegmentResponse =
1515
await config.containerUrl.listBlobFlatSegment(Aborter.none, marker);
1616
marker = listBlobsResponse.nextMarker;
1717
const deletePromises = listBlobsResponse.segment.blobItems.map(
1818
async (blobItem: Models.BlobItem) => {
1919
const blobUrl = BlobURL.fromContainerURL(config.containerUrl, blobItem.name);
20+
/* istanbul ignore else - Unnecessary to test */
2021
if (blobItem.name.startsWith(config.subFolder)) {
2122
await blobUrl.delete(Aborter.none);
2223
}
2324
},
2425
);
2526
await Promise.all(deletePromises);
26-
} while (marker !== '');
27+
}
2728
};
2829
};

src/apps/activities/azureStorageRepo/getProfileContent.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export default (config: Config) => {
1111

1212
const blobUrl = BlobURL.fromContainerURL(config.containerUrl, filePath);
1313
const content = (await blobUrl.download(Aborter.none, 0)).readableStreamBody;
14+
15+
/* istanbul ignore if - Difficult to test */
1416
if (content === undefined) {
1517
throw new Error('Blob not found');
1618
}

0 commit comments

Comments
 (0)