Skip to content

Commit 5f85a63

Browse files
committed
split up modules in a naive way. Next step is getting config split up correctly.
1 parent c99f15e commit 5f85a63

File tree

8 files changed

+394
-95
lines changed

8 files changed

+394
-95
lines changed

__tests__/TESTING.md

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Testing
2+
3+
4+
## Integration Tests
5+
6+
### Troubleshooting Integration Tests
7+
8+
#### `AggregateError` doesn't tell me what went wrong
9+
Wrap the "expect" statements of the offending test in a `try/catch` block and print the error like so:
10+
```javascript
11+
try {
12+
expect(foo).toEqual(bar);
13+
} catch (e) {
14+
console.log("Aggregate Error: ", e);
15+
}
16+
```
17+
18+
TODO: Maybe write a custom reporter
19+
20+
#### I want to know what request the container actually received
21+
There are two options here:
22+
1. In the `afterAll` block, comment out the code that runs the container teardown. After the test fails, you can run `docker logs -f nginx-s3-gateway-test-base`
23+
24+
2. Before the code that is erroring, add `timeout(3000)` then quickly run `docker logs -f nginx-s3-gateway-test-base` in another tab after the container starts.

__tests__/basic.test.js

+155-52
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
2-
const Minio = require("minio");
31
const request = require("supertest");
2+
const container = require("./support/container.js");
3+
const s3Mock = require("./support/s3Mock.js");
4+
5+
const TEST_NAME = "base";
46

57
const FILES = {
68
"a.txt": {
@@ -18,56 +20,123 @@ const FILES = {
1820
"Throw it away!"
1921
"With not one thing, what there is to throw away?"
2022
"Then carry it off!"
23+
`,
24+
},
25+
"b/c/=": {
26+
content: `
27+
This is an awful filename.
28+
このフィール名を選ばないでください
29+
`
30+
},
31+
"b/c/@": {
32+
content: ""
33+
},
34+
"b/c/'(1).txt": {
35+
content: "In the midst of movement and chaos, keep stillness inside of you."
36+
},
37+
"a/plus+plus.txt": {
38+
content: `
39+
代悲白頭翁   Lament for the White-Haired Old Man
40+
洛陽城東桃李花 In the east of Luoyang City, Peach blossoms abound
41+
飛來飛去落誰家 Their petals float around, coming and going, to whose house will they fall?
42+
洛陽女児惜顔色 Girls in Luoyang cherish their complexion
43+
行逢落花長歎息 They breathe a deep sigh upon seeing the petals fall
44+
今年花落顔色改 This year the petals fall and their complexion changes
45+
明年花開復誰在 Who will be there when the flowers bloom next year?
46+
已見松柏摧為薪 I've seen the pines and cypresses destroyed and turned into firewood
47+
更聞桑田変成海 I hear that the mulberry fields have fallen into the sea
48+
古人無復洛城東 The people of old never came back to the east of Luoyang City
49+
今人還對落花風 The people of today likewise face the falling flowers in the wind
50+
年年歳歳花相似 Year after year, flowers look alike
51+
歳歳年年人不同 Year after year, the people are not the same
52+
寄言全盛紅顔子 I want you to get this message, my child, you are in your prime, with a rosy complexion
53+
應憐半死白頭翁 Take pity on the half-dead white-haired old man
54+
此翁白頭真可憐 You really must take pity on this white-haired old man
55+
伊昔紅顔美少年 For once upon a time, I used to be a red-faced handsome young man
56+
公子王孫芳樹下 A child of noble birth under a fragrant tree
57+
清歌妙舞落花前 Singing and dancing in front of the falling petals
58+
光禄池臺開錦繍 At the platform before the mirror pond, beautiful autumn leaves opening all around
59+
将軍楼閣畫神仙 The general’s pavilion is painted with gods and goddesses
60+
一朝臥病無相識 Once I was sick and no one knew me
61+
三春行楽在誰邉 Who will be at the shore for the spring outing?
62+
宛轉蛾眉能幾時 For how long will the moths gracefully turn about?
63+
須臾鶴髪亂如絲 The crane’s feathers are like tangled threads for just a moment
64+
但看古来歌舞地 Yet, look at the ancient places of song and dance
65+
惟有黄昏鳥雀悲 Only in twilight, do the birds lament
66+
`
67+
},
68+
"системы/%bad%file%name%": {
69+
content: `
70+
Filename encoding issues are hard.
71+
2172
`
2273
}
2374
};
2475

2576
const BUCKET_NAME = "bucket-2";
26-
const GATEWAY_HOST = "localhost";
27-
const GATEWAY_PORT = "8989";
28-
const GATEWAY_BASE_URL = `http://${GATEWAY_HOST}:${GATEWAY_PORT}`;
29-
30-
beforeAll(async () => {
31-
const minioClient = new Minio.Client({
32-
endPoint: "localhost",
33-
port: 9090,
34-
useSSL: false,
35-
accessKey: 'AKIAIOSFODNN7EXAMPLE',
36-
secretKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
37-
});
3877

39-
await ensureBucketWithObjects(minioClient, BUCKET_NAME, FILES);
78+
// Config for the running container per test
79+
80+
const CONFIG = container.Config({
81+
env: {
82+
S3_BUCKET_NAME: BUCKET_NAME,
83+
AWS_ACCESS_KEY_ID: "AKIAIOSFODNN7EXAMPLE",
84+
AWS_SECRET_ACCESS_KEY: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
85+
S3_SERVER: "minio",
86+
S3_SERVER_PORT: "9000",
87+
S3_SERVER_PROTO: "http",
88+
S3_REGION: "us-east-1",
89+
DEBUG: "true",
90+
S3_STYLE: "virtual",
91+
ALLOW_DIRECTORY_LIST: "false",
92+
PROVIDE_INDEX_PAGE: "",
93+
APPEND_SLASH_FOR_POSSIBLE_DIRECTORY: "",
94+
STRIP_LEADING_DIRECTORY_PATH: "",
95+
PREFIX_LEADING_DIRECTORY_PATH: "",
96+
AWS_SIGS_VERSION: "4",
97+
STATIC_SITE_HOSTING: "",
98+
PROXY_CACHE_MAX_SIZE: "10g",
99+
PROXY_CACHE_INACTIVE: "60m",
100+
PROXY_CACHE_VALID_OK: "1h",
101+
PROXY_CACHE_VALID_NOTFOUND: "1m",
102+
PROXY_CACHE_VALID_FORBIDDEN: "30s",
103+
},
104+
dockerfileName: "Dockerfile.oss",
105+
testName: TEST_NAME,
106+
networkName: "s3-gateway-test",
40107
});
41108

42-
async function ensureBucketWithObjects(s3Client, bucketName, objects) {
43-
if (await s3Client.bucketExists(BUCKET_NAME)) {
44-
await s3Client.removeObjects(BUCKET_NAME, Object.keys(FILES));
45-
await s3Client.removeBucket(BUCKET_NAME);
109+
const minioClient = s3Mock.Client("localhost", 9090, "AKIAIOSFODNN7EXAMPLE", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY");
110+
111+
beforeAll(async () => {
112+
try {
113+
await container.stop(CONFIG);
114+
} catch (e) {
115+
console.log("no container to stop");
46116
}
47117

48-
await s3Client.makeBucket(BUCKET_NAME, 'us-east-1');
118+
await s3Mock.ensureBucketWithObjects(minioClient, BUCKET_NAME, FILES);
119+
await container.build(CONFIG);
120+
await container.start(CONFIG);
121+
});
122+
123+
afterAll(async () => {
124+
await container.stop(CONFIG);
125+
await s3Mock.deleteBucket(minioClient, BUCKET_NAME);
126+
});
49127

50-
for (const path of Object.keys(FILES)) {
51-
console.log(`now loading file ${path}`);
52-
let buf = Buffer.from(FILES[path].content, "utf-8");
53-
let res = await s3Client.putObject(BUCKET_NAME, path, buf);
54-
console.log(`Uploaded file: ${JSON.stringify(res)}`);
55-
}
56-
}
57128

58129
describe("Ordinary filenames", () => {
59130
test("simple url", async () => {
60131
const objectPath = "a.txt";
61-
const res = await request(GATEWAY_BASE_URL)
62-
.get(`/${objectPath}`);
63-
132+
const res = await request(CONFIG.testContainer.baseUrl).get(`/${objectPath}`);
64133
expect(res.statusCode).toBe(200);
65134
expect(res.text).toBe(FILES[objectPath].content);
66135
});
67136

68137
test("many params that should be stripped", async () => {
69138
const objectPath = "a.txt";
70-
const res = await request(GATEWAY_BASE_URL)
139+
const res = await request(CONFIG.testContainer.baseUrl)
71140
.get("/a.txt?some=param&that=should&be=stripped#aaah")
72141
.set("accept", "binary/octet-stream");
73142

@@ -77,27 +146,28 @@ describe("Ordinary filenames", () => {
77146

78147
test("with a more complex path", async () => {
79148
const objectPath = "b/c/d.txt";
80-
const res = await request(GATEWAY_BASE_URL)
149+
const res = await request(CONFIG.testContainer.baseUrl)
81150
.get("/b/c/d.txt")
82151
.set("accept", "binary/octet-stream");
83152

84153
expect(res.statusCode).toBe(200);
85154
expect(res.text).toBe(FILES[objectPath].content);
86155
});
87156

88-
test("with a more complex path", async () => {
157+
test.skip("with dot segments in the path", async () => {
89158
const objectPath = "b/e.txt";
90-
const res = await request(GATEWAY_BASE_URL)
159+
const res = await request(CONFIG.testContainer.baseUrl)
91160
.get("/b/c/../e.txt")
92161
.set("accept", "binary/octet-stream");
93162

163+
const reqData = JSON.parse(JSON.stringify(res)).req;
94164
expect(res.statusCode).toBe(200);
95165
expect(res.text).toBe(FILES[objectPath].content);
96166
});
97167

98168
test("another simple path", async () => {
99169
const objectPath = "b/e.txt";
100-
const res = await request(GATEWAY_BASE_URL)
170+
const res = await request(CONFIG.testContainer.baseUrl)
101171
.get("/b/e.txt")
102172
.set("accept", "binary/octet-stream");
103173

@@ -107,7 +177,7 @@ describe("Ordinary filenames", () => {
107177

108178
test("too many forward slashes", async () => {
109179
const objectPath = "b/e.txt";
110-
const res = await request(GATEWAY_BASE_URL)
180+
const res = await request(CONFIG.testContainer.baseUrl)
111181
.get("/b//e.txt")
112182
.set("accept", "binary/octet-stream");
113183

@@ -116,9 +186,12 @@ describe("Ordinary filenames", () => {
116186
});
117187

118188
test("very long file name", async () => {
119-
const objectPath = "a/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.txt";
120-
const res = await request(GATEWAY_BASE_URL)
121-
.get("/a/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.txt")
189+
const objectPath =
190+
"a/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.txt";
191+
const res = await request(CONFIG.testContainer.baseUrl)
192+
.get(
193+
"/a/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.txt",
194+
)
122195
.set("accept", "binary/octet-stream");
123196

124197
expect(res.statusCode).toBe(200);
@@ -127,23 +200,53 @@ describe("Ordinary filenames", () => {
127200
});
128201

129202
describe("strange file names and encodings", () => {
203+
test("URI encoded equal sign as file name", async () => {
204+
const objectPath = "b/c/=";
205+
const res = await request(CONFIG.testContainer.baseUrl)
206+
.get("/b/c/%3D")
207+
.set("accept", "binary/octet-stream");
208+
209+
expect(res.statusCode).toBe(200);
210+
expect(res.text).toBe(FILES[objectPath].content);
211+
});
130212

131-
})
213+
test("URI encoded @ symbol as file name", async () => {
214+
const objectPath = "b/c/@";
215+
const res = await request(CONFIG.testContainer.baseUrl)
216+
.get("/b/c/%40")
217+
.set("accept", "binary/octet-stream");
218+
219+
expect(res.statusCode).toBe(200);
220+
expect(res.text).toBe(FILES[objectPath].content);
221+
});
132222

133-
// # We try to request URLs that are properly encoded as well as URLs that
134-
// # are not properly encoded to understand what works and what does not.
223+
test("URI with encoded punctuation in file name", async () => {
224+
const objectPath = "b/c/'(1).txt";
225+
const res = await request(CONFIG.testContainer.baseUrl)
226+
.get("/b/c/%27%281%29.txt")
227+
.set("accept", "binary/octet-stream");
135228

136-
// # Weird filenames
137-
// assertHttpRequestEquals "HEAD" "b/c/%3D" "200"
138-
// assertHttpRequestEquals "HEAD" "b/c/=" "200"
229+
expect(res.statusCode).toBe(200);
230+
expect(res.text).toBe(FILES[objectPath].content);
231+
});
139232

140-
// assertHttpRequestEquals "HEAD" "b/c/%40" "200"
141-
// assertHttpRequestEquals "HEAD" "b/c/@" "200"
233+
test("URI with encoded plus in file name", async () => {
234+
const objectPath = "a/plus+plus.txt";
235+
const res = await request(CONFIG.testContainer.baseUrl)
236+
.get("/a/plus%2Bplus.txt")
237+
.set("accept", "binary/octet-stream");
142238

143-
// assertHttpRequestEquals "HEAD" "b/c/%27%281%29.txt" "200"
144-
// assertHttpRequestEquals "HEAD" "b/c/'(1).txt" "200"
239+
expect(res.statusCode).toBe(200);
240+
expect(res.text).toBe(FILES[objectPath].content);
241+
});
145242

146-
// # These URLs do not work unencoded
147-
// assertHttpRequestEquals "HEAD" 'a/plus%2Bplus.txt' "200"
148-
// assertHttpRequestEquals "HEAD" "%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B/%25bad%25file%25name%25" "200"
243+
test("URI with cyrillic script and punctuation in file name", async () => {
244+
const objectPath = "системы/%bad%file%name%";
245+
const res = await request(CONFIG.testContainer.baseUrl)
246+
.get("/%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D1%8B/%25bad%25file%25name%25")
247+
.set("accept", "binary/octet-stream");
149248

249+
expect(res.statusCode).toBe(200);
250+
expect(res.text).toBe(FILES[objectPath].content);
251+
});
252+
});

0 commit comments

Comments
 (0)