@@ -5,13 +5,14 @@ import (
55 "fmt"
66 "net/http"
77 "os"
8+ "time"
89
910 "github.com/go-resty/resty/v2"
1011 "github.com/rs/zerolog"
1112 "github.com/smartcontractkit/chainlink-testing-framework/parrot"
1213)
1314
14- func ExampleServer_Register () {
15+ func ExampleServer_Register_internal () {
1516 // Create a new parrot instance with no logging and a custom save file
1617 saveFile := "register_example.json"
1718 p , err := parrot .Wake (parrot .WithLogLevel (zerolog .NoLevel ), parrot .WithSaveFile (saveFile ))
@@ -48,30 +49,47 @@ func ExampleServer_Register() {
4849 }
4950 fmt .Println (resp .StatusCode ())
5051 fmt .Println (string (resp .Body ()))
52+
53+ // Get all routes from the parrot instance
54+ routes := p .Routes ()
55+ fmt .Println (len (routes ))
56+
57+ // Delete the route
58+ err = p .Delete (route .ID ())
59+ if err != nil {
60+ panic (err )
61+ }
62+
63+ // Get all routes from the parrot instance
64+ routes = p .Routes ()
65+ fmt .Println (len (routes ))
5166 // Output:
5267 // 200
5368 // Squawk
69+ // 1
70+ // 0
5471}
5572
56- func ExampleRoute () {
57- // Run the parrot server as a separate instance, like in a Docker container
58- saveFile : = "route_example.json"
59- p , err := parrot . Wake ( parrot . WithPort ( 9090 ), parrot . WithLogLevel ( zerolog . NoLevel ), parrot . WithSaveFile ( saveFile ))
60- if err != nil {
61- panic ( err )
62- }
63- defer func () { // Cleanup the parrot instance
64- err = p . Shutdown ( context . Background ()) // Gracefully shutdown the parrot instance
73+ func ExampleServer_Register_external () {
74+ var (
75+ saveFile = "route_example.json"
76+ port = 9090
77+ )
78+ defer os . Remove ( saveFile ) // Cleanup the save file for the example
79+
80+ go func () { // Run the parrot server as a separate instance, like in a Docker container
81+ _ , err := parrot . Wake ( parrot . WithPort ( port ), parrot . WithLogLevel ( zerolog . NoLevel ), parrot . WithSaveFile ( saveFile ))
6582 if err != nil {
6683 panic (err )
6784 }
68- p .WaitShutdown () // Wait for the parrot instance to shutdown. Usually unnecessary, but we want to clean up the save file
69- os .Remove (saveFile ) // Cleanup the save file for the example
7085 }()
7186
7287 // Code that calls the parrot server from another service
7388 // Use resty to make HTTP calls to the parrot server
7489 client := resty .New ()
90+ client .SetBaseURL (fmt .Sprintf ("http://localhost:%d" , port )) // The URL of the parrot server
91+
92+ waitForParrotServer (client , time .Second ) // Wait for the parrot server to start
7593
7694 // Register a new route /test that will return a 200 status code with a text/plain response body of "Squawk"
7795 route := & parrot.Route {
@@ -80,7 +98,7 @@ func ExampleRoute() {
8098 RawResponseBody : "Squawk" ,
8199 ResponseStatusCode : http .StatusOK ,
82100 }
83- resp , err := client .R ().SetBody (route ).Post ("http://localhost:9090 /routes" )
101+ resp , err := client .R ().SetBody (route ).Post ("/routes" )
84102 if err != nil {
85103 panic (err )
86104 }
@@ -89,7 +107,7 @@ func ExampleRoute() {
89107
90108 // Get all routes from the parrot server
91109 routes := make ([]* parrot.Route , 0 )
92- resp , err = client .R ().SetResult (& routes ).Get ("http://localhost:9090 /routes" )
110+ resp , err = client .R ().SetResult (& routes ).Get ("/routes" )
93111 if err != nil {
94112 panic (err )
95113 }
@@ -98,10 +116,7 @@ func ExampleRoute() {
98116 fmt .Println (len (routes ))
99117
100118 // Delete the route
101- req := & parrot.RouteRequest {
102- ID : route .ID (),
103- }
104- resp , err = client .R ().SetBody (req ).Delete ("http://localhost:9090/routes" )
119+ resp , err = client .R ().SetBody (route ).Delete ("/routes" )
105120 if err != nil {
106121 panic (err )
107122 }
@@ -110,7 +125,7 @@ func ExampleRoute() {
110125
111126 // Get all routes from the parrot server
112127 routes = make ([]* parrot.Route , 0 )
113- resp , err = client .R ().SetResult (& routes ).Get ("http://localhost:9090 /routes" )
128+ resp , err = client .R ().SetResult (& routes ).Get ("/routes" )
114129 if err != nil {
115130 panic (err )
116131 }
@@ -125,7 +140,7 @@ func ExampleRoute() {
125140 // 0
126141}
127142
128- func ExampleRecorder () {
143+ func ExampleRecorder_internal () {
129144 saveFile := "recorder_example.json"
130145 p , err := parrot .Wake (parrot .WithLogLevel (zerolog .NoLevel ), parrot .WithSaveFile (saveFile ))
131146 if err != nil {
@@ -147,7 +162,7 @@ func ExampleRecorder() {
147162 }
148163
149164 // Register the recorder with the parrot instance
150- err = p .Record (recorder .URL )
165+ err = p .Record (recorder .URL () )
151166 if err != nil {
152167 panic (err )
153168 }
@@ -194,3 +209,107 @@ func ExampleRecorder() {
194209 // 200
195210 // Squawk
196211}
212+
213+ // Example of how to use parrot recording when calling it from an external service
214+ func ExampleRecorder_external () {
215+ var (
216+ saveFile = "recorder_example.json"
217+ port = 9091
218+ )
219+ defer os .Remove (saveFile ) // Cleanup the save file for the example
220+
221+ go func () { // Run the parrot server as a separate instance, like in a Docker container
222+ _ , err := parrot .Wake (parrot .WithPort (port ), parrot .WithLogLevel (zerolog .NoLevel ), parrot .WithSaveFile (saveFile ))
223+ if err != nil {
224+ panic (err )
225+ }
226+ }()
227+
228+ client := resty .New ()
229+ client .SetBaseURL (fmt .Sprintf ("http://localhost:%d" , port )) // The URL of the parrot server
230+
231+ waitForParrotServer (client , time .Second ) // Wait for the parrot server to start
232+
233+ // Register a new route /test that will return a 200 status code with a text/plain response body of "Squawk"
234+ route := & parrot.Route {
235+ Method : http .MethodGet ,
236+ Path : "/test" ,
237+ RawResponseBody : "Squawk" ,
238+ ResponseStatusCode : http .StatusOK ,
239+ }
240+
241+ // Register the route with the parrot instance
242+ resp , err := client .R ().SetBody (route ).Post ("/routes" )
243+ if err != nil {
244+ panic (err )
245+ }
246+
247+ // Use the host of the machine your recorder is running on
248+ // This should not be localhost if you are running the parrot server on a different machine
249+ // It should be the public IP address of the machine running your code, so that the parrot can call back to it
250+ host := "localhost"
251+
252+ // Create a new recorder with our host
253+ recorder , err := parrot .NewRecorder (parrot .WithHost (host ))
254+ if err != nil {
255+ panic (err )
256+ }
257+
258+ // Register the recorder with the parrot instance
259+ resp , err = client .R ().SetBody (recorder ).Post ("/record" )
260+ if err != nil {
261+ panic (err )
262+ }
263+ if resp .StatusCode () != http .StatusCreated {
264+ panic (fmt .Sprintf ("failed to register recorder, got %d status code" , resp .StatusCode ()))
265+ }
266+
267+ go func () { // Some other service calls the /test route
268+ _ , err := client .R ().Get ("/test" )
269+ if err != nil {
270+ panic (err )
271+ }
272+ }()
273+
274+ // You can now listen to the recorder for all route calls
275+ for {
276+ select {
277+ case recordedRouteCall := <- recorder .Record ():
278+ if recordedRouteCall .RouteID == route .ID () {
279+ fmt .Println (recordedRouteCall .RouteID )
280+ fmt .Println (recordedRouteCall .Request .Method )
281+ fmt .Println (recordedRouteCall .Response .StatusCode )
282+ fmt .Println (string (recordedRouteCall .Response .Body ))
283+ return
284+ }
285+ case err := <- recorder .Err ():
286+ panic (err )
287+ }
288+ }
289+ // Output:
290+ // GET:/test
291+ // GET
292+ // 200
293+ // Squawk
294+ }
295+
296+ // waitForParrotServer checks the parrot server health endpoint until it returns a 200 status code or the timeout is reached
297+ func waitForParrotServer (client * resty.Client , timeoutDur time.Duration ) {
298+ ticker := time .NewTicker (50 * time .Millisecond )
299+ defer ticker .Stop ()
300+ timeout := time .NewTimer (timeoutDur )
301+ for { // Wait for the parrot server to start
302+ select {
303+ case <- ticker .C :
304+ resp , err := client .R ().Get ("/health" )
305+ if err != nil {
306+ continue
307+ }
308+ if resp .StatusCode () == http .StatusOK {
309+ return
310+ }
311+ case <- timeout .C :
312+ panic ("timeout waiting for parrot server to start" )
313+ }
314+ }
315+ }
0 commit comments