-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: using the developer plugin (#246)
Co-authored-by: Sophia Chu <[email protected]> Co-authored-by: Sophia Chu <[email protected]> Co-authored-by: Karen <[email protected]> Co-authored-by: Sophia Chu <[email protected]>
- Loading branch information
1 parent
93cbe61
commit ccf63a0
Showing
2 changed files
with
148 additions
and
0 deletions.
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
docs/using-the-nodejs-wrapper/using-plugins/UsingTheDeveloperPlugin.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
## Developer Plugin | ||
|
||
> [!WARNING] | ||
> The plugin is NOT intended to be used in production environments. It's designed for the purpose of testing. | ||
The Developer Plugin allows developers to inject an error to a connection and to verify how an application handles it. | ||
|
||
Since some errors raised by the drivers rarely happen, testing for those might be difficult and require a lot of effort in building a testing environment. Errors associated with network outages are a good example of those errors. It may require substantial efforts to design and build a testing environment where such timeout errors could be produced with 100% accuracy and 100% guarantee. If a test suite can't produce and verify such cases with 100% accuracy it significantly decreases the value of such tests and makes the tests unstable and flaky. The Developer Plugin simplifies testing of such scenarios as shown below. | ||
|
||
The `dev` plugin code should be added to the connection plugins parameter in order to be able to intercept calls and raise a test error when conditions are met. | ||
|
||
### Simulate an error while opening a new connection | ||
|
||
The plugin introduces a new class `ErrorSimulationManager` that will handle how a given error will be passed to the connection to be tested. | ||
|
||
In order to raise a test error while opening a new connection, first create an instance of the error to be tested, then use `raiseErrorOnNextConnect` in `ErrorSimulationManager` so it will be triggered at next connection attempt. | ||
|
||
Once the error is raised, it will be cleared and will not be raised again. This means that the next opened connection will not raise the error again. | ||
|
||
```ts | ||
params = { | ||
plugins: "dev" | ||
}; | ||
|
||
const client = new AwsPGClient(params); | ||
|
||
const testErrorToRaise: Error = new Error("test"); | ||
ErrorSimulatorManager.raiseErrorOnNextConnect(testErrorToRaise); | ||
|
||
await client.connect(); // that throws the error | ||
|
||
await client.connect(); // it goes normal with no error | ||
``` | ||
|
||
### Simulate an error with already opened connection | ||
|
||
It is possible to also simulate an error thrown in a connection after the connection has been opened. | ||
|
||
Similar to previous case, the error is cleared up once it's raised and subsequent calls should behave normally. | ||
|
||
```ts | ||
params = { | ||
plugins: "dev" | ||
}; | ||
|
||
const client = new AwsPGClient(params); | ||
await client.connect(); | ||
|
||
const simulator: ErrorSimulator = client.getPluginInstance<ErrorSimulator>(DeveloperConnectionPlugin); | ||
const testErrorToRaise: Error = new Error("test"); | ||
simulator.raiseErrorOnNextCall(testErrorToRaise, "query"); | ||
|
||
const result = await client.query("select 1"); // that throws the error | ||
const anotherResult = await client.query("select 1"); // it goes normal with no error | ||
``` | ||
|
||
It's possible to use a callback functions to check call parameters and decide whether to return an error or not. Check `ErrorSimulatorManager.setCallback` and `ErrorSimulator.setCallback` for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
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. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import { AwsPGClient } from "../../pg/lib"; | ||
import { ErrorSimulatorManager } from "../../common/lib/plugins/dev/error_simulator_manager"; | ||
import { DeveloperConnectionPlugin } from "../../common/lib/plugins/dev/developer_connection_plugin"; | ||
import { ErrorSimulator } from "../../common/lib/plugins/dev/error_simulator"; | ||
import { ErrorSimulatorMethodCallback } from "../../common/lib/plugins/dev/error_simulator_method_callback"; | ||
|
||
const postgresHost = "db-identifier.XYZ.us-east-2.rds.amazonaws.com"; | ||
const username = "john_smith"; | ||
const password = "password"; | ||
const database = "employees"; | ||
const port = 5432; | ||
|
||
const errorToRaise = new Error("test"); | ||
|
||
const client = new AwsPGClient({ | ||
// Configure connection parameters. | ||
host: postgresHost, | ||
port: port, | ||
user: username, | ||
password: password, | ||
database: database, | ||
plugins: "dev" | ||
}); | ||
|
||
// Simulate an exception while opening a new connection. | ||
ErrorSimulatorManager.raiseErrorOnNextConnect(errorToRaise); | ||
|
||
// Attempt connection. Throws errorToRaise. | ||
try { | ||
await client.connect(); | ||
} catch { | ||
// Handle errorToRaise. | ||
} | ||
|
||
// Another connection. Goes normal with no error. | ||
await client.connect(); | ||
|
||
// Simulate an error with already opened connection. | ||
const simulator: ErrorSimulator = client.getPluginInstance<ErrorSimulator>(DeveloperConnectionPlugin); | ||
simulator.raiseErrorOnNextCall(errorToRaise, "query"); | ||
|
||
// Query throws errorToRaise. | ||
try { | ||
const result = await client.query("select 1"); | ||
} catch { | ||
// Handle errorToRaise. | ||
} | ||
|
||
// Query executes normally without error. | ||
const anotherResult = await client.query("select 1"); | ||
|
||
// Check call parameters to decide whether to return an exception or not. | ||
class TestErrorCallback implements ErrorSimulatorMethodCallback { | ||
getErrorToRaise<T>(methodName: string, methodArgs: any): Error | null { | ||
if (methodName == "query" && methodArgs == "select 1") { | ||
return errorToRaise; | ||
} | ||
return null; | ||
} | ||
} | ||
|
||
simulator.setCallback(new TestErrorCallback()); | ||
|
||
// Queries that do not match the parameters will execute normally. | ||
const mismatch = await client.query("select 2"); | ||
|
||
// Query throws errorToRaise. | ||
try { | ||
const match = await client.query("select 1"); | ||
} catch { | ||
// Handle errorToRaise. | ||
} | ||
|
||
// Close connection. | ||
await client.end(); |