浏览代码

Add TypeScript Deno + MongoDB Raw Test Cases (#6445)

* Update standard library version from `v0.50.0` to `0.87.0`

* Update standard library version from `v0.50.0` to `0.87.0`

* Refactor Deno test cases (1)

* Refactor Deno test cases(2)

* Refactor Deno test cases (3)

* Fix Dockerfile

* Update Deno `mongo` to 0.22.0

* Fix Deno `dockerfile`

* Update Deno Docker

* Fix Deno `dyn_date`

* Fix Deno `dyn_date`

* Fix Deno  `dyn_date`

* Fix Deno `export`

* Fix Deno `dyn_date`

* Add Deno `mongodb-raw` Test Cases

* Add Deno `mongodb-raw` Test Cases

* Fix Deno `main.ts` import error

* Fix Number Resolve

* Fix `resolveQueryNumber`&`generateFortunes`

* *Debug* Updates Error

* Fix fillArray()

* Update Deno version

* Update MongoClient Version

* Update Deno Http Version

* Back Mongo Client Version

* Change Deno std version

* Change Deno std Version

* Fix Types & Delete Debug Log

* Fix Dockerfile

* Fix Dockerfile

* Update build.yml

* Update build.yml
Oxygen 4 年之前
父节点
当前提交
f3b037a85e

+ 41 - 20
frameworks/TypeScript/deno/benchmark_config.json

@@ -1,21 +1,42 @@
 {
-  "framework": "deno",
-  "tests": [{
-    "default": {
-      "json_url": "/json",
-      "plaintext_url": "/plaintext",
-      "port": 8080,
-      "approach": "Realistic",
-      "classification": "Platform",
-      "framework": "None",
-      "language": "TypeScript",
-      "flavor": "deno",
-      "platform": "deno",
-      "webserver": "None",
-      "os": "Linux",
-      "database_os": "Linux",
-      "display_name": "deno",
-      "versus": "nodejs"
-    }
-  }]
-}
+    "framework": "deno",
+    "tests": [{
+        "default": {
+            "json_url": "/json",
+            "plaintext_url": "/plaintext",
+            "port": 8080,
+            "approach": "Realistic",
+            "classification": "Platform",
+            "language": "TypeScript",
+            "flavor": "deno",
+            "platform": "deno",
+            "webserver": "None",
+            "os": "Linux",
+            "database_os": "Linux",
+            "display_name": "deno",
+            "versus": "nodejs"
+        },
+        "mongodb-raw": {
+            "dockerfile": "deno.mongoraw.dockerfile",
+            "json_url": "/json",
+            "plaintext_url": "/plaintext",
+            "db_url": "/db",
+            "query_url": "/queries?queries=",
+            "update_url": "/updates?queries=",
+            "fortune_url": "/fortunes",
+            "port": 8080,
+            "approach": "Realistic",
+            "classification": "Platform",
+            "database": "MongoDB",
+            "orm": "Raw",
+            "language": "TypeScript",
+            "flavor": "deno",
+            "platform": "deno",
+            "webserver": "None",
+            "os": "Linux",
+            "database_os": "Linux",
+            "display_name": "deno",
+            "versus": "nodejs"
+        }
+    }]
+}

+ 18 - 0
frameworks/TypeScript/deno/config.toml

@@ -17,3 +17,21 @@ orm = "Raw"
 platform = "deno"
 webserver = "None"
 versus = "nodejs"
+
+[mongodb]
+urls.plaintext = "/plaintext"
+urls.json = "/json"
+urls.db = "/db"
+urls.query = "/queries?queries="
+urls.update = "/updates?queries="
+urls.fortune = "/fortunes"
+urls.cached_query = "/cached?queries="
+approach = "Realistic"
+classification = "Platform"
+database = "MongoDB"
+database_os = "Linux"
+os = "Linux"
+orm = "Raw"
+platform = "nodejs"
+webserver = "None"
+versus = "nodejs"

+ 1 - 1
frameworks/TypeScript/deno/deno.dockerfile

@@ -1,4 +1,4 @@
-FROM hayd/alpine-deno:1.8.1
+FROM hayd/alpine-deno:latest
 
 EXPOSE 8080
 

+ 18 - 0
frameworks/TypeScript/deno/deno.mongoraw.dockerfile

@@ -0,0 +1,18 @@
+FROM hayd/alpine-deno:latest
+
+
+EXPOSE 8080
+
+WORKDIR /app
+
+USER deno
+ENV DATABASE mongodb
+
+COPY ./src .
+
+RUN deno cache main.mongoraw.ts
+
+EXPOSE 8080
+
+CMD ["run", "--allow-net", "main.mongoraw.ts"]
+

+ 37 - 13
frameworks/TypeScript/deno/src/_handlers/mongodb-raw/_db_helpers.ts → frameworks/TypeScript/deno/src/_handlers/mongodb-raw/database.ts

@@ -10,9 +10,9 @@ export let Fortune = client.database(dbName).collection("fortune");
 
 export const randomNumber = (): number => Math.floor(Math.random() * 10000) + 1;
 
-export const fillArray = async <T = any>(v: T, l: number) => {
+export const fillArrayWithFn = async<T = any>(v: Function, l: number) => {
   let o = [];
-  for (let i = 0; i < l; i += 1) o.push(v);
+  for (let i = 0; i < l; i += 1) o.push(await v());
   return o;
 };
 
@@ -21,6 +21,17 @@ export interface FortuneData {
   message: string;
   _id?: unknown;
 }
+export const htmlEncodeByRegExp = (str: string) => {
+  let s = "";
+  if (str.length == 0) return "";
+  s = str.replaceAll(/&/g, "&amp;");
+  s = s.replaceAll(/</g, "&lt;");
+  s = s.replaceAll(/>/g, "&gt;");
+  // s = s.replaceAll(/ /g, "&nbsp;");
+  s = s.replaceAll(/\'/g, "'");
+  s = s.replaceAll(/\"/g, '"');
+  return s;
+};
 export const _fortunes_head = [
   "<!DOCTYPE html>",
   "<html>",
@@ -34,18 +45,19 @@ export const _fortunes_head = [
 ].join("");
 export const _fortunes_end = ["</table>", "</body>", "</html>"].join("");
 export const _fortunes_com = ["<tr>", "</tr>", "<td>", "</td>"];
-export const generateFortunes = (input: FortuneData[]): string => {
+export const generateFortunes = (input: FortuneData[]) => {
   let f = input
-    .map(
-      (v) =>
-        _fortunes_com[0] +
-        +_fortunes_com[2] +
-        v.id +
-        _fortunes_com[3] +
-        _fortunes_com[2] +
-        v.message +
-        _fortunes_com[3] +
-        _fortunes_com[1]
+    .map((v) =>
+      [
+        _fortunes_com[0],
+        _fortunes_com[2],
+        v.id.toString(),
+        _fortunes_com[3],
+        _fortunes_com[2],
+        htmlEncodeByRegExp(v.message),
+        _fortunes_com[3],
+        _fortunes_com[1],
+      ].join("")
     )
     .join("");
 
@@ -85,3 +97,15 @@ export const additionalFortune = {
   id: 0,
   message: "Additional fortune added at request time.",
 };
+
+export const resolveQueryNumber = (s: string) => {
+  let r: number;
+  if (/^\d+$/.test(s)) {
+    r = Number(s);
+    if (r > 500) r = 500;
+    if (r < 1) r = 1;
+  } else {
+    r = 1;
+  }
+  return r;
+};

+ 1 - 1
frameworks/TypeScript/deno/src/_handlers/mongodb-raw/fortunes.ts

@@ -4,7 +4,7 @@ import {
   additionalFortune,
   generateFortunes,
   FortuneData,
-} from "./_db_helpers.ts";
+} from "./database.ts";
 
 export const headers = new Headers([
   ["server", SERVER],

+ 12 - 0
frameworks/TypeScript/deno/src/_handlers/mongodb-raw/handlers.ts

@@ -0,0 +1,12 @@
+import { Handlers } from "./../../handlers.ts";
+import FortunesHandler from "./fortunes.ts";
+import MultipleQueriesHandler from "./multiple-queries.ts";
+import SingleQueryHandler from "./single-query.ts";
+import UpdatesHandler from "./updates.ts";
+
+export const MongoRawHandlers = {
+  "/db": SingleQueryHandler,
+  "/queries": MultipleQueriesHandler,
+  "/updates": UpdatesHandler,
+  "/fortunes": FortunesHandler,
+} as Handlers;

+ 3 - 3
frameworks/TypeScript/deno/src/_handlers/mongodb-raw/multiple-queries.ts

@@ -1,5 +1,5 @@
 import { ServerRequest, SERVER, dyn_date, MIME_JSON } from "../../depends.ts";
-import { randomWorld, fillArray } from "./_db_helpers.ts";
+import { randomWorld, fillArrayWithFn, resolveQueryNumber } from "./database.ts";
 
 export const headers = new Headers([
   ["server", SERVER],
@@ -8,8 +8,8 @@ export const headers = new Headers([
 
 export default async (req: ServerRequest): Promise<void> => {
   const u = new URL(req.url, "http://deno");
-  const l = Number(u.searchParams.get("queries"));
-  const rnd = await Promise.all(await fillArray(randomWorld(), l));
+  const l = resolveQueryNumber(u.searchParams.get("queries") ?? "1");
+  const rnd = await Promise.all(await fillArrayWithFn(() => randomWorld(), l));
   headers.set("date", dyn_date());
   req.respond({
     headers,

+ 1 - 1
frameworks/TypeScript/deno/src/_handlers/mongodb-raw/single-query.ts

@@ -1,5 +1,5 @@
 import { ServerRequest, SERVER, dyn_date, MIME_JSON } from "../../depends.ts";
-import { randomWorld } from "./_db_helpers.ts";
+import { randomWorld } from "./database.ts";
 
 export const headers = new Headers([
   ["server", SERVER],

+ 3 - 3
frameworks/TypeScript/deno/src/_handlers/mongodb-raw/updates.ts

@@ -1,5 +1,5 @@
 import { ServerRequest, SERVER, dyn_date, MIME_JSON } from "../../depends.ts";
-import { updateQuery, fillArray } from "./_db_helpers.ts";
+import { updateQuery, fillArrayWithFn, resolveQueryNumber } from "./database.ts";
 
 export const headers = new Headers([
   ["server", SERVER],
@@ -8,8 +8,8 @@ export const headers = new Headers([
 
 export default async (req: ServerRequest): Promise<void> => {
   const u = new URL(req.url, "http://deno");
-  const l = Number(u.searchParams.get("queries"));
-  const rnd = await Promise.all(await fillArray(updateQuery(), l));
+  const l = resolveQueryNumber(u.searchParams.get("queries") ?? "1");
+  const rnd = await Promise.all(await fillArrayWithFn(() => updateQuery(), l));
   headers.set("date", dyn_date());
   req.respond({
     headers,

+ 2 - 2
frameworks/TypeScript/deno/src/depends.ts

@@ -1,9 +1,9 @@
-export type { Response } from "https://deno.land/std@0.87.0/http/server.ts";
+export type { Response } from "https://deno.land/std@0.96.0/http/server.ts";
 
 export {
   ServerRequest,
   serve,
-} from "https://deno.land/std@0.87.0/http/server.ts";
+} from "https://deno.land/std@0.96.0/http/server.ts";
 
 export { MongoClient, Bson } from "https://deno.land/x/[email protected]/mod.ts";
 

+ 5 - 4
frameworks/TypeScript/deno/src/handlers.ts

@@ -2,15 +2,16 @@ import type { ServerRequest } from "./depends.ts";
 import JSONHandler from "./_handlers/json.ts";
 import PlaintextHandler from "./_handlers/plaintext.ts";
 
-interface Handler {
+export interface Handler {
   (request: ServerRequest): Promise<void>;
 }
 
-interface Handlers {
+export interface Handlers {
   [index: string]: Handler;
 }
 
-export const handlers: Handlers = {
+export default {
   "/json": JSONHandler,
   "/plaintext": PlaintextHandler,
-};
+} as Handlers;
+

+ 22 - 0
frameworks/TypeScript/deno/src/main.mongoraw.ts

@@ -0,0 +1,22 @@
+import { serve } from "https://deno.land/[email protected]/http/server.ts";
+import DefaultHandlers from "./handlers.ts";
+import { MongoRawHandlers } from "./_handlers/mongodb-raw/handlers.ts";
+const handlers = {
+  ...DefaultHandlers,
+  ...MongoRawHandlers,
+};
+
+for await (const req of serve("0.0.0.0:8080")) {
+  const url = new URL(req.url, "http://deno");
+  if (handlers[url.pathname] != undefined) {
+    handlers[url.pathname](req as any).catch((e) => {
+      console.error(e);
+      Deno.exit(9);
+    });
+  } else {
+    req.respond({
+      body: "404 Not Found",
+    });
+  }
+  continue;
+}

+ 4 - 4
frameworks/TypeScript/deno/src/main.ts

@@ -1,8 +1,8 @@
-import { serve } from "https://deno.land/std@0.87.0/http/server.ts";
-import { handlers } from "./handlers.ts";
+import { serve } from "https://deno.land/std@0.96.0/http/server.ts";
+import Handlers from "./handlers.ts";
 for await (const req of serve("0.0.0.0:8080")) {
-  if (handlers[req.url] != undefined) {
-    handlers[req.url](req).catch((e) => {
+  if (Handlers[req.url] != undefined) {
+    Handlers[req.url](req as any).catch((e) => {
       console.error(e);
       Deno.exit(9);
     });

+ 70 - 0
frameworks/TypeScript/deno/src/tsconfig.json

@@ -0,0 +1,70 @@
+{
+  "compilerOptions": {
+    /* Visit https://aka.ms/tsconfig.json to read more about this file */
+
+    /* Basic Options */
+    // "incremental": true,                   /* Enable incremental compilation */
+    "target": "esnext",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
+    "module": "esnext",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
+    // "lib": [],                             /* Specify library files to be included in the compilation. */
+    // "allowJs": true,                       /* Allow javascript files to be compiled. */
+    // "checkJs": true,                       /* Report errors in .js files. */
+    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
+    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
+    // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
+    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
+    // "outFile": "./",                       /* Concatenate and emit output to single file. */
+    // "outDir": "./",                        /* Redirect output structure to the directory. */
+    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
+    // "composite": true,                     /* Enable project compilation */
+    // "tsBuildInfoFile": "./",               /* Specify file to store incremental compilation information */
+    // "removeComments": true,                /* Do not emit comments to output. */
+    // "noEmit": true,                        /* Do not emit outputs. */
+    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
+    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
+    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
+
+    /* Strict Type-Checking Options */
+    "strict": false,                           /* Enable all strict type-checking options. */
+    "noImplicitAny": false,                 /* Raise error on expressions and declarations with an implied 'any' type. */
+    // "strictNullChecks": true,              /* Enable strict null checks. */
+    "strictFunctionTypes": false,           /* Enable strict checking of function types. */
+    // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
+    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
+    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
+    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */
+
+    /* Additional Checks */
+    // "noUnusedLocals": true,                /* Report errors on unused locals. */
+    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
+    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
+    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */
+    // "noUncheckedIndexedAccess": true,      /* Include 'undefined' in index signature results */
+
+    /* Module Resolution Options */
+    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
+    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
+    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
+    // "typeRoots": [],                       /* List of folders to include type definitions from. */
+    // "types": [],                           /* Type declaration files to be included in compilation. */
+    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
+    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
+    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
+    // "allowUmdGlobalAccess": true,          /* Allow accessing UMD globals from modules. */
+
+    /* Source Map Options */
+    // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
+    // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
+    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
+    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
+
+    /* Experimental Options */
+    "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
+    "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
+
+    /* Advanced Options */
+    "skipLibCheck": true,                     /* Skip type checking of declaration files. */
+    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
+  }
+}