Code Monkey home page Code Monkey logo

ambassador's People

Contributors

chandlerdea avatar fangpenlin avatar geroherkenrath avatar jannash avatar joe-spectrum avatar kdubb avatar ltetzlaff avatar mazyod avatar thisisjak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ambassador's Issues

Add badges

Below the title please add badges for carthage compatibility, SwiftPM compatibility (not your case), Swift version and platform compatibility like this:

Carthage compatible SwiftPM compatible Swift Version Plaform

Nested Routers?

Hi,

As Router implements WebApp protocol, I assumed I could nest routers as follows:

let userRouter = Router()
userRouter["/create"] = ...
userRouter["/list"] = ...

let rootRouter = Router()
router["/user"] = userRouter

That doesn't seem to work. Whenever I hit /user path, the WebApp assigned to /create always gets run, regardless of the subpath.

Is this a known limitation? Is there interest in getting contributors implementing this?

Thanks,
Maz

Different response data and status codes

Hi,

is there a way to switch the response data and response code on every request?

I have ui test which should return a 401 status code in the first two requests and in the third request it should return a 200 response. Is there a way to get this working?

Retrieving request Headers through Router

Is it possible to get request headers using Ambassador? I can't seem to find them in the environ variable alongside the other information.

I expected to find custom headers or most common ones inside a environ field.

DataReader gives empty result.

I run a http server for my ui test. In order to check the app's request, I defined a route and tried to read the request body with DataReader as described.

Everything works fine except reading the body. Most time the body is empty.
The following should demonstrate the problem:

mockServer.router["/test"] = JSONResponse() { requestInfo -> Any in
  let bodyStream = requestInfo["swsgi.input"] as! SWSGIInput
  DataReader.read(bodyStream) { data in
    let text = String(data: data, encoding: .utf8)
    print(text)
  }
  print("return response")
  return []
}
        
var request = URLRequest(url: URL(string: "http://localhost:8080/test")!, cachePolicy: NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 10)
request.httpMethod = "POST"
request.httpBody = "test value".data(using: .utf8)
URLSession(configuration: URLSessionConfiguration.default).dataTask(with: request).resume()
print("request sent")

Most time the read text is empty and I get the following output:

request sent
return response
Optional("")

Sometimes the text is correct and I get the following output:

request sent
Optional("test value")
return response

As you can see, the data is read after the response was returned here.

Please help me to solve this problem. Without this problem the library would be great.

I think it's also interesting that it works this way, without a router:

server = DefaultHTTPServer(eventLoop: eventLoop, port: 8080) {
    (
    environ: [String: Any],
    startResponse: ((String, [(String, String)]) -> Void),
    sendBody: ((Data) -> Void)
    ) in
    // Start HTTP response
    let pathInfo = environ["PATH_INFO"]! as! String
    let bodyStream = environ["swsgi.input"] as! SWSGIInput
    DataReader.read(bodyStream) { data in
        let text = String(data: data, encoding: .utf8)
        print(text)
    }
    startResponse("200 OK", [])
}

Swift 3+ runForever example

Do you have an example of running your DefaultHTTPServer asynchronously in the background using Swift 3.0 or greater? I would like to use Ambassador in an XCTest ( i.e. NOT XCUITest) to build a lightweight mock REST server for unit testing an API that I'm building.

Thanks in advance,
Rowland

App Lockup

Using the exact example code, after running the server..the app freezes, but the server is still accessible. Any ideas as to what may be going wrong? If I comment out loop.runForever() it doesn't happen..but the server doesn't work. using Xcode 9 on iOS 11 Swift 3.

import Embassy
import EnvoyAmbassador

let loop = try! SelectorEventLoop(selector: try! KqueueSelector())
let router = Router()
let server = DefaultHTTPServer(eventLoop: loop, port: 8080, app: router.app)

router["/api/v2/users"] = DelayResponse(JSONResponse(handler: { _ -> Any in
    return [
        ["id": "01", "name": "john"],
        ["id": "02", "name": "tom"]
    ]
}))

// Start HTTP server to listen on the port
try! server.start()

// Run event loop
loop.runForever()```

Server returning previous router response on high memory load

Has anyone seen on occasion that multiple tests to the same endpoint with different responses sometimes causes the test to fail on high memory load?

I ensure that between tests the server is stopped and cleaned up, however, if two tests run one after the other sometimes the previous response is returned. This happens mostly when the machine is under high memory load.

Using a mixture of both DelayResponse and DataResponse to return expected JSON payloads and DataResponses such as 400 Bad Request.

Providing path to json file instead of content of the json.

Instead of providing the JSON format structure after return, is there a way to point Ambassador to the .json file located in the project of the app we want to test?

instead of

router["/api/v2/users"] = JSONResponse() { _ -> Any in
    return [
        ["id": "01", "name": "john"],
        ["id": "02", "name": "tom"]
    ]
}

something like:

router["/api/v2/users"] = JSONResponse() { _ -> Any in
    return [
       path/to/file/users.json
    ]
}

Similar endpoints

When I ran this code from Router class in Playgrounds always print "matches" for similar endpoints. In my case, Ambassador is returning the same JSON response to both endpoints and I don't know why...Is there a chance that similar endpoints make Ambassador confused? (Sometimes work sometimes don't)

`
let path = "foo/bar/10/xyz"
let searchPath = "foo/bar/10/xyz/asd"
let regex = try! NSRegularExpression(pattern: path, options: [])
let matches = regex.matches(in: searchPath, options: [], range: NSRange(location: 0, length: searchPath.count))

if !matches.isEmpty {
print("match")
} else {
print("no match")
}
`

Reading request data

As readme says to read request data we can use DataRead.read(input) { data in ... } in request handler. This does not work for me as reading block is called asynchronously after request handler returns, so I can not use it to build data to send back. If I try to wait for this block without exiting handler connections is getting stuck.

What I want to accomplish is to redirect all requests that are not stubbed to real server (because it's just insane to stub every request in the flow when you need to test one particular case on the screen that is deep inside navigation and app needs to make dozen of requests before reaching it). Here is my code:

struct RedirectResponse: WebApp {
    
    // where to redirect
    let host: String
    let scheme: String
    
    func urlRequest(_ environ: [String: Any]) -> URLRequest {
        //reading environment variables and transforming header keys to their initial values....
        return request
    }
    
    public func app(_ environ: [String : Any], startResponse: @escaping ((String, [(String, String)]) -> Swift.Void), sendBody: @escaping ((Data) -> Swift.Void)) {
        var request = urlRequest(environ)
        let input = environ["swsgi.input"] as! SWSGIInput
        DataReader.read(input) { data in
       // this block is called only after method returns, which is too late as request was already fired.
       // Waiting for this block to be called before firing request keeps connection stuck and block is never called
            request.httpBody = data 
        }
        // makes request and wait for response in synchronous manner, using `group.wait()`
        let (data, statusCode, contentType, headers) = URLSession.shared.data(with: request)
        //send data from real server back
        DataResponse(statusCode: statusCode, statusMessage: "", contentType: contentType, headers: headers, handler: { (_, sendData) in
            sendData(data)
        }).app(environ, startResponse: startResponse, sendBody: sendBody)
    }
    
}

Then I set this response as notFoundResponse for the router.

With that I receive such logs:

2017-02-03 13:03:58 +0000 [info] - DefaultHTTPServer: New connection 87A6CC41-5E67-4585-944D-C409FDC9D16A from [::1]:58322
2017-02-03 13:03:58 +0000 [info] - HTTPConnection: [87A6CC41-5E67-4585-944D-C409FDC9D16A] Header parsed, method=Optional("POST"), path="/auth/oauth2/client/access_token", version="HTTP/1.1", headers=[("Host", "localhost:8080"), ("Accept-Encoding", "gzip;q=1.0, compress;q=0.5"), ("mobile-app", "IOS-838"), ("Accept-Language", "en-US;q=1.0, en;q=0.9"), ("Content-Length", "177"), ("Content-Type", "application/json"), ("Accept", "*/*"), ("Connection", "keep-alive"), ("User-Agent", "Alamofire/4.2.0")]
2017-02-03 13:03:58 +0000 [info] - HTTPConnection: [87A6CC41-5E67-4585-944D-C409FDC9D16A] Resume reading
2017-02-03 13:03:58 +0000 [info] - HTTPConnection: [87A6CC41-5E67-4585-944D-C409FDC9D16A] Finish response
2017-02-03 13:03:58 +0000 [info] - HTTPConnection: [87A6CC41-5E67-4585-944D-C409FDC9D16A] Connection closed, reason=byLocal

Request fails as it does not contain required body data.

When trying to wait for read data block:

2017-02-03 13:01:35 +0000 [info] - DefaultHTTPServer: New connection 6DB9C3DF-02E3-49F5-8801-22EB0CE58AF5 from [::1]:58286
2017-02-03 13:01:35 +0000 [info] - HTTPConnection: [6DB9C3DF-02E3-49F5-8801-22EB0CE58AF5] Header parsed, method=Optional("POST"), path="/auth/oauth2/client/access_token", version="HTTP/1.1", headers=[("Host", "localhost:8080"), ("Accept-Encoding", "gzip;q=1.0, compress;q=0.5"), ("mobile-app", "IOS-838"), ("Accept-Language", "en-US;q=1.0, en;q=0.9"), ("Content-Length", "177"), ("Content-Type", "application/json"), ("Accept", "*/*"), ("Connection", "keep-alive"), ("User-Agent", "Alamofire/4.2.0")]
2017-02-03 13:01:35 +0000 [info] - HTTPConnection: [6DB9C3DF-02E3-49F5-8801-22EB0CE58AF5] Resume reading

and then request fails with timeout.

Here is the request that app makes:

curl -i \
	-X POST \
	-H "mobile-app: IOS-838" \
	-H "Content-Type: application/json" \
	-H "Accept-Encoding: gzip;q=1.0, compress;q=0.5" \
	-H "Accept-Language: en-US;q=1.0, en;q=0.9" \
	-H "User-Agent: Alamofire/4.2.0" \
	-d "{\"country\":\"us\",\"locale\":\"en-US\",\"grant_type\":\"client_credentials\",\"client_id\":\"...\",\"client_secret\":\"...\",\"scope\":\"public\"}" \
	"http://localhost:8080/auth/oauth2/client/access_token"

Hanging redirects

I noticed that stubbing requests with redirect responses makes server to "hang" with these stubs making it impossible to override this stub with another response. That does not happen for simple responses though. I was able to override it only after I deleted UI tests target from simulator.

Here is how I stub request with redirect (the reset of the code is taken from the blog article):

let response = DataResponse(statusCode: 301, statusMessage: "Moved Permanently", headers: [("Location", "http://www.example.org/")])
router[DefaultRouter.fetchUsersPath] = DelayResponse(response)

Even if I comment out these lines and run the test again I keep receiving redirect response.

Supporting different states of a mocked response

Hey guys,

just wondering because I didn't find a doc about this, but what we have a case of doing a mock to different states of the same response.
for example:
/welcome api will return "Hi World" and then on subsequent /welcome needs to be returned like “Hi Globe”

is there a way to play around this that could enable me to mock the response in states
because my issue now is that the UI test just continue without waiting the response to be fully mocked (same response) or it just override everything to the latest mock

Thanks so much guys for your support that I really need because I am stuck in this for quite some time :)

Consecutive API calls

Hey @victorlin,

I am writing UI tests using Envoy/Ambassy. I have a test case that makes a second API call when the first one is successfull. I receive the response data from the Ambassy after the first API call, but it fails to respond for the second API call. It waits for the response forever, and finally the test quits with the UI test timeout.

I am setting up the router for each API path as in the following:

func testUserRegistrationSuccess() {
      router[DefaultRouter.fetchActivationPath] = DataResponse(
            statusCode: 200,
            statusMessage: "created",
            contentType: "application/json",
            headers: [("Link", app.launchEnvironment["ENVOY_BASEURL"]! + DefaultRouter.fetchConfigApiPath), ("X-SubscriptionID","0000001"), ("X-DeviceAuthorizationToken", "oue97twieurgsljdfh")]     
        ) { (environ, sendData) in
            sendData([])
        }

        router[DefaultRouter.fetchConfigApiPath] = DelayResponse(JSONResponse(
            statusCode: 200,
            statusMessage: "Configs updated",
            contentType: "application/json",
            headers: [("X-SubscriptionID","0000002"), ("X-DeviceAuthorizationToken", "oue97twieurgsljdfh")],
            handler: { _ in
                return ["trip_url" : "return-tripLink", "trip_key" : "return-tripKey", "host_page" : "return-hostPage", "ruleset_uri" : "return-autoStartRulesetURL"]
        }), delay: .Delay(seconds: 4) )

       app.launch()
      // here goes the UI test. 
      RegistrationHelper.registerSuccessfull(app)
}

This is the output log of the App side :

2016-10-11 16:58:25.560 App[37875:30667532] request authorization succeeded!
2016-10-11 16:58:39.915 App[37875:30667260] AccountActivationRequest, url=http://localhost:8080/activate
2016-10-11 16:58:41.571 App[37875:30667260] AccountActivationRequest - request: http://localhost:8080/activate
2016-10-11 16:58:47.928 App[37875:30667260] AccountActivationRequest - response: <NSHTTPURLResponse: 0x6100004264e0> { URL: http://localhost:8080/activate } { status code: 200, headers {
    Connection = close;
    "Content-Length" = 0;
    "Content-Type" = "application/json";
    Link = "http://localhost:8080/configsApi";
    Server = Embassy;
    "X-DeviceAuthorizationToken" = oue97twieurgsljdfh;
    "X-SubscriptionID" = 0000001;
} }
2016-10-11 16:58:47.932 App[37875:30667260] Config Request urlStr=http://localhost:8080/configsApi

and the output of the UI test is as in the following:

t =    92.21s     Tap Button
    t =    92.21s         Wait for app to idle
    t =    92.26s         Find the Button
    t =    92.26s             Snapshot accessibility hierarchy for com.mydrivesolutions.mydriveapp.debug
    t =    92.50s             Find: Descendants matching type Table
    t =    92.50s             Find: Descendants matching type Cell
    t =    92.51s             Find: Element at index 5
    t =    92.51s             Find: Children matching type Button
    t =    92.51s             Wait for app to idle
    t =    92.56s         Synthesize event
    t =    92.81s         Wait for app to idle
    t =   106.25s     Tap "OK" Button
    t =   106.25s         Wait for app to idle
    t =   108.22s         Find the "OK" Button
    t =   108.22s             Snapshot accessibility hierarchy for com.mydrivesolutions.mydriveapp.debug
    t =   112.42s             Find: Descendants matching type Button
    t =   127.80s             Assertion Failure: <unknown>:0: UI Testing Failure - Failure fetching attributes for element <XCAccessibilityElement: 0x61800045ca40> Device element: Error Domain=XCTestManagerErrorDomain Code=13 "Error copying attributes -25204" UserInfo={NSLocalizedDescription=Error copying attributes -25204}
    t =   127.80s             Assertion Failure: RegistrationHelper.swift:97: UI Testing Failure - Failed to get attributes within 15.0s: (
    3003
)
    t =   127.80s             Tear Down
    t =   127.80s                 Terminate <XCUIApplicationProcess: 0x6000000b08c0 com.test.testapp.debug (54231)>
Test Case '-[mainUITests.MyUITests testUserRegistrationSuccess]' failed (127.840 seconds).
Test Suite 'MyUITests' failed at 2016-10-12 10:34:10.745.
     Executed 1 test, with 2 failures (0 unexpected) in 127.840 (127.843) seconds
Test Suite 'mainUITests.xctest' failed at 2016-10-12 10:34:10.745.
     Executed 1 test, with 2 failures (0 unexpected) in 127.840 (127.843) seconds
Test Suite 'Selected tests' failed at 2016-10-12 10:34:10.746.
     Executed 1 test, with 2 failures (0 unexpected) in 127.840 (127.845) seconds

2016-10-12 10:34:11.043 XCTRunner[54203:31284087] no more background tasks running

I am using the UITestBase class, which you have posted in the article about how to use EnvoyAmbassador and Embassy, at https://envoy.engineering/embedded-web-server-for-ios-ui-testing-8ff3cef513df#.9vlx7so14
What would be the best approach to mock two consecutive API calls using Ambassy?

Local server not responding to requests

I am able to connect to the local server on port 8080, but it does not respond to requests. Here is what it looks like when I curl:

screen shot 2016-07-31 at 8 12 43 pm

I used the code from your medium post to setup and tear down the local server:

`private extension UITests {

func startHTTPServer() {
    self.eventLoop = try! SelectorEventLoop(selector: try! KqueueSelector())
    self.router = DefaultRouter()
    self.server = HTTPServer(eventLoop: self.eventLoop, app: self.router.app, port: self.port)
    try! self.server.start()
    self.eventLoopThreadCondition = NSCondition()
    self.eventLoopThread = NSThread(target: self, selector: #selector(self.runEventLoop), object: nil)
    self.eventLoopThread.start()
}

func stopHTTPServer() {
    self.server.stopAndWait()
    self.eventLoopThreadCondition.lock()
    self.eventLoop.stop()
    while self.eventLoop.running {
        if !self.eventLoopThreadCondition.waitUntilDate(NSDate().dateByAddingTimeInterval(10)) {
            fatalError("Join eventLoopThread timeout")
        }
    }
}

@objc func runEventLoop() {
    self.eventLoop.runForever()
    self.eventLoopThreadCondition.lock()
    self.eventLoopThreadCondition.signal()
    self.eventLoopThreadCondition.unlock()
}

}`

Let me know if you have any questions that I can answer.

Support and contribution to this library

Hey @victorlin ,

We have started some work with Xcode UI test framework and interested in exploring this library to support mocking for our network calls during test execution.I went through the details on Github page of Embassy and Ambassador and their integration for XCUI* APIs seems seamless.Could you provide some details on the current support status of the framework and plan for maintaining this framework in future? Are there any areas of improvement where you are looking for any contribution (e.g Swift 2.3 support, Carthage )?

Thanks,
Sushant

New Release For Embassy

Can you publish a new release for Embassy. It has fixes for target not found issue in SPM but there is no release for the fix.

Router mixing similar routes

Possible bug in Router, we have an api with two very similar paths /api/GetDevices and /api/GetDevice, while trying to ui test in iOS after setting up a response for each endpoint some times we're getting GetDevice's response for a call to GetDevices which makes the tests crash as the response is different and cannot be parsed by our app. I think the problem is in the matcher that sometimes is mixing responses in case of similar routes like ours.

Running server in the different thread

First of all, thanks for the help you already gave me, it really helped me a lot. But I have another one.

I wonder if it possible to completely move server to run on background. I know that we move an event loop to run on a different thread, than the testrunner, but the thing is when, for example, I want to have a breakpoint inside a test, the server itself does also stop responding. Also I noticed, that the testrunner thread is too busy doing queries and other stuff leaving the server too little bandwidth, so I see the response time is increasing to the great extent. If that's not possible, I wonder if we can somehow prioritize server over the testrunner stuff.

Update cocoapods version

Aloha Envoy team!

The cocoapods version is still a tiny bit behind, it doesn't include @fangpenlin's PR #28.
Since my project uses cocoapods I still get a warning during builds (that's the only one, so kinda prominent).

I had actually already forked the repo and wanted to fix the deprecated call to characters, I was really confused when master already had the latest Swift syntax. 😸

Maybe one of you can quickly do a tag, version bump etc. and push to the cocoapods spec repo?

Thanks a lot, your Embassy & Ambassador have really helped me a lot in testing (and since it's all swift I can keep my repo nice and clean!).

Multi-part form upload returns empty data using DataReader

Can someone give an example of how to handle POST requests where we are uploading files/photos (multipart/form-data).

I tried to use DataReader(input) snippet but that always gives me an empty data back. Does environ need to have another key set ? Looking at python's uwsgi definitions, they advise to use cgi.FieldStorage.

d = cgi.FieldStorage(environ=environ, fp=environ['wsgi.input'], keep_blank_values=True)

Could you provide an example of how do we handle this case ?

DataReader.read(input) { d in print(d) }

In this case, when using
curl -v -X POST -F '[email protected]' http://localhost:8080/image , the d variable declared above is nil.

Get query string from a request

I'm trying to get the query string arguments from an URL similar to: /v2/users?direction=past&limit=20. Is there a way to get those parameters and their values inside a router to form response based on those parameters? I did try to use URLParametersReader, but it returns an empty object every time.

Response body gets cut off

When trying to get all the data from response body with DataReader it works fine when receiving small amount of data, but when trying to get a bigger body response, it doesn’t return the whole data, but only a part of it. I could fix it by increasing recvChunkSize to the size bigger that I was trying to read. But seems like the problem is in chunking itself, but I wasn’t able to debug it more deeply.

Has anyone encountered this kind of problem?

Server gets stuck on stop

I have the following test in my XCTestCase, which should demonstrate the problem.

let mockServer = MockServer()
mockServer.start()

mockServer.router["/test"] = JSONResponse() { _ -> NSDictionary in
    print("request received")
    return [:]
}

print("Send request")
URLSession(configuration: URLSessionConfiguration.default)
    .dataTask(with: URL(string: "http://localhost:8080/test")!)
    .resume()

sleep(3) // Any action or tear down delay.
print("stop mock server")
mockServer.stop() // Never ends
print("mock server stopped")

MockServer is a wrapper I have made, which handles starting and stopping the server.
I followed your gist about running the server.

class MockServer {
    let router = Router()
    private let server: HTTPServer
    private let serverDispatchQueue = DispatchQueue(label: "com.timr.uitest.serverDispatchQueue", qos: .background)
    private let eventLoop: EventLoop
    private var eventLoopThreadCondition = NSCondition()
    
    init() {
        eventLoop = try! SelectorEventLoop(selector: try! KqueueSelector())
        server = DefaultHTTPServer(
            eventLoop: eventLoop,
            port: 8080,
            app: router.app
        )
    }
    
    func start() {
        try! server.start()
        eventLoopThreadCondition = NSCondition()
        serverDispatchQueue.async() {
            self.eventLoop.runForever()
            self.eventLoopThreadCondition.lock()
            self.eventLoopThreadCondition.signal()
            self.eventLoopThreadCondition.unlock()
        }
    }
    
    func stop() {
        server.stopAndWait()
        eventLoopThreadCondition.lock()
        eventLoop.stop()
        let stopEventLoopTimeout = 10.0
        while eventLoop.running {
            if !eventLoopThreadCondition.wait(until: Date(timeIntervalSinceNow: stopEventLoopTimeout)) {
                fatalError("Join eventLoopThread timeout")
            }
        }
    }
}

The problem is that the test never ends because it gets stuck at server.stopAndWait().
I get this output:

Send request
request received
stop mock server

As I digged a bit deeper I found out that the last event loop round does not finish. So the action awaited in stopAndWait, which is passed to eventLoop.call never gets called.
runOncein EventLoop gets stuck at events = try selector.select(timeout: timeout).

Would be great if you could take a look on this issue @fangpenlin. This problem is a bit too deep for me.

Fatal error with iOS 16 in TCPSocket

Getting the following error:
Thread 1: Fatal error: self must be a properly aligned pointer for types Pointee and T
in TCPSocket pointing to withMemoryRebound:

func bind(port: Int, interface: String = "::", addressReusable: Bool = true) throws {
        // make address reusable
        if addressReusable {
            var reuse = Int32(1)
            guard setsockopt(
                fileDescriptor,
                SOL_SOCKET,
                SO_REUSEADDR,
                &reuse,
                socklen_t(MemoryLayout<Int32>.size)
            ) >= 0 else {
                throw OSError.lastIOError()
            }
        }
        // create IPv6 socket address
        var address = sockaddr_in6()
        #if !os(Linux)
        address.sin6_len = UInt8(MemoryLayout<sockaddr_in6>.stride)
        #endif
        address.sin6_family = sa_family_t(AF_INET6)
        address.sin6_port = UInt16(port).bigEndian
        address.sin6_flowinfo = 0
        address.sin6_addr = try ipAddressToStruct(address: interface)
        address.sin6_scope_id = 0
        let size = socklen_t(MemoryLayout<sockaddr_in6>.size)
        // bind the address and port on socket
        guard withUnsafePointer(to: &address, { pointer in
            return pointer.withMemoryRebound(to: sockaddr.self, capacity: Int(size)) { pointer in
                return SystemLibrary.bind(fileDescriptor, pointer, size) >= 0
            }
        }) else {
            throw OSError.lastIOError()
        }
    }

Adding some related context:
https://forums.swift.org/t/on-properly-aligned-pointer-for-types-pointee-and-t/61325/4

Cheers

Inconsistent data from request.

I'm using EnvoyAmbassador in unit tests to mock my API server. In order to validate the JSON body that the software under test sends, I'm using DataReader.read(input) like below. This works fine most of the time, but sometimes it fails. When it does fail, it looks like there's no data read by the DataReader(input) method. In the case below, the buffer has length 0.

Give the sporadic nature of the error, it feels like it might be a race condition? Any clues as to why this might fail once in a while?

        if let input = environ["swsgi.input"] as? SWSGIInput {
            let buffer = NSMutableData()
            DataReader.read(input) { data in
                for var d in data {     // data is list of UInt8
                    buffer.appendData(NSData(bytes: &d, length: sizeof(UInt8)))
                }
            }
            swiftyJson = JSON(data: buffer)
            if (buffer.length == 0) {
                XCTFail("Found zero length buffer parsing JSON")
            }

Performance issues when running tests on parallel

When I'm trying to run some UI tests on parallel with a local server on every simulator, those servers are responding very slowly, sometimes response time can be 2-3 seconds, sometimes even more. I'm wondering what can cause such a delay when running tests on parallel, because when running on one simulator, server gives response quickly enough.

Delay response doesnt work as expected

Hello guys,

I noticed that when I use delay response in ui test, and in this response I return some value to assert in UI test, delayed response sometimes come after I made assertion.

So, first I mock response with delay like this router["/api/v2/users"] = DelayResponse(JSONResponse(......)), and after I assert value I got from response file, or assert ui element that I enabled in this mocked response. So this kind of tests are flaky, because depending on delay time, it gives back response after assertion.

Deleting delay response solves this flakiness. But why it happens with DelayResponse?

Fatal error with xcode 14 with Bad file descriptor

Hi all, after upgrading to xcode 14 we are getting a error on both M1 rossetta and intel:

Embassy/SelectorEventLoop.swift:88: Fatal error: 'try!' expression unexpectedly raised an error: Embassy.OSError.ioError(number: 9, message: "Bad file descriptor")

This happens after trying to restart (teardown-setup) a local server
image

testing with multiple iOS versions, testing with other xcode versions later.

Anyone else run into this?

Websocket support

Is there any plans for implementing websocket support? Or is there any available extensions? I googled it and failed to find any neither for Ambassador no for embassy.

Thanks.

Router an API with parameters

Hey Guys,
wondering is there an example how to use DataResponse with URLParametersReader
I am having an API with parameters and I need to router it with DataResponse
router["someAPI?WithParam1&Param2"]

and I am using the DataResponse()
Your help is so much needed and appreciated!

Support many states api responses

Hello.

Is there any way to support many states API responses such as:

  • Call Login success will be responded:
router["/api/v2/login"] = DelayResponse(JSONStringResponse(handler: { _ -> Any in
    return """
        {
          "acess_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
        }
    """
}))
  • Call login failed will be responded:
router["/api/v2/login"] = DelayResponse(JSONStringResponse(handler: { _ -> Any in
    return """
        {
          "message": "incorrect password"
        }
    """
}))

I mean I want to test a feature (login) with many cases as many API responses. Seem to now only one state can setup before a test.

Thank you so much.

working sample

I would love to use this library, but would really appreciate a working example in swift 4 of ui testing / unit testing using Ambassador. The current steps listed appear to freeze the app on Xcode 9.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.