I have a C# module responsible for acquiring the list of network adapters that are "connected to the internet" on a windows Vista machine. The module uses the "Network List Manager API" (or NLM API) to iterate over all network connections and returns all those for which the IsConnectedToInternet value is true.
I received some suggestions for the implementation of this module in this SO question
To test this module I've decided to write a helper that returns the list of internet connected interfaces based on another logic, so it would be a sort of a "reality check" for the original module's logic. Note that for the test helper I am willing to use detection methods that might be considered bad practice for production code (e.g. relying on some internet resource like "Google" to be available - in case it shuts down, blocked by our internal firewall etc. it's relatively easy to fix the test as opposed to a deployed product base).
The alternative detection method I chose was to try to connect to "www.google.com:80" with a TcpClient. My problem: When I have more than one connected adapter (e.g. both wireless and LAN) the detection method fails for one of them with the error "A connect request was made on an already-connected socket".
My question is three fold:
How would you go about testing such a module in general? Do you support the idea of doing the same thing in a different way and comparing the results or is it an overkill and I should rely on the system's API? My main problem here, is that it's very hard to pre-configure the system so that I'll know what the expected results are in advance.
What alternative logic would you suggest? One thing that was suggested in the aforementioned question was looking at the routing table - what about considering each adapter that has a routing entry with a destination of 0.0.0.0 as "connected to the internet"? Other suggestions?
Do you understand why I get the "already-connected" error with the current test logic?
I can only answer your question about the unit test.
The code you're testing is, in your own words, "a C# module responsible for acquiring the list of network adapters that are 'connected to the internet' on a windows Vista machine. The module uses the 'Network List Manager API' (or NLM API) to iterate over all network connections and returns all those for which the IsConnectedToInternet value is true."
If I were writing this module, I would first use an interface for the NLM API, call it...NLMAPIService. Now, for the real code, create an Adapter that implements NLMAPIService and adapts the real NLM API.
For testing, create a class FakeNLMAPI that implements NLMAPIService and has all of its data in-memory somewhere, or in an XML file, or whatever. Your module calls methods only on the NLMAPIService, so you don't have to change any "real" code depending on whether you're testing or not.
Therefore, in your test setup method, you can instantiate FakeNLMAPI and pass it to your module, and in production, instantiate your NLM API Adapter.
I'm going to assume that you can instantiate and modify the object that represents a network connection. If not, you can follow the same pattern for faking the actual network connection object.
Dependency Injection is a very handy pattern to deal with issues like this. Instead of simply using the NLM API components directly in your code define an interface and a class that implements it and serves as a proxy to the NLM API. Pass an instance of this class to your module in the constructor and have your module use it. In your unit tests, instead of the real proxy object, use a mock object that returns known information -- it doesn't even have to reference the NLM API -- to use in testing the logic of your module. Granted, your proxy class will need some testing as well, but the logic in it is much simpler -- probably just some data marshaling. You might be able to convince yourself of its correctness or, if not, do some manual testing on it to make sure that it is working properly.
UnitTests shouldn't access to external resources. To UnitTest your method, I would stub out the Network List Manager API.
You still need an acceptance test layer. In that test environment you should replicate various configurations you expect to support in your environment, setup your own webhosts, routers, machine config. Acceptance testing should be done at the user experience level using a tool like Fitnesse.
Related
I've been working with a golang application lately that does network i/o using a bunch of protocols- HTTP (TCP), DNS and WHOIS (UDP) as well as a few others. Some make use of third-party APIs
The application is open-source so I would like to make changes allowing me to specify the network interface for the sockets to bind to, allowing me to use different interfaces depending on a runtime flag. The only way around this without writing code would be to modify the system-wide routing table each time I want to utilize a different interface, which isn't a very appealing solution
Before I go an modify every instance where a Dialer is used (or try to create a wrapper that they can all use) is there a golang feature that would allow setting the interface globally once, so that the various Dialer invocations would "Just Work"- and adhere to the interface I specified?
I did some searching and have only found ways to do this when each Dialer is created (using DialerContext.LocalAddr) but given I'm really a C programmer and not a golang programmer, I realize I may be totally missing a golang idiom for doing something like this
I maintain a web API written in Ruby. It connects to many third party web services. When writing tests, I stub any function that would need to connect to the network and return bottled data instead.
It has happened to me before that I forget this stubbing step, and my integration tests end up actually connecting to a third party service.
With that in mind, I would like to prevent Ruby from being able to open network connections. When attempted, I would like it to raise an exception instead, pointing out what function I forgot to stub.
Is this possible? What central Ruby function would I need to override to achieve this with minimal other side effects?
What about WebMock? Did you try it? https://github.com/bblimke/webmock
This line should help:
WebMock.disable_net_connect!(allow_localhost: true)
Manual stubbing is, as you've just said, unreliable.
A better solution might be to wrap your code that calls external services behind a facade, and use dependency injection to pass the web handling service into the facade on creation. Your Test Suite then just needs to do the same with a stub service. You'd only need to do this once, and any test which was then testing external code would use the stubbed service.
Check out VCR.
First, take a look at its documentation and see if it's what you need, which I suppose it is. We've been using it at my company for a few years to record one HTTP test for a spec and replay the results for subsequent tests.
We've found it to be invaluable when dealing with external APIs.
When to use Channel Factory, and When to use Service Proxy in WCF?
My binding is NetNamedPipeBinding. and I'm planning to use a Duplex connection.
When to use a proxy?
We create proxy using svcutil.exe. The output of this tool gives a proxy class and makes corresponding changes to the application configuration file. If you have a service that you know is going to be used by several applications or is generic enough to be used in several places, you'll want to continue using the generated proxy classes. We use proxy in WCF to be able to share the service contract and entities with the client. Proxies have several restrictions like they need to have gets and sets , contructors can't be exposed , methods other than the service contract cannot be exposed, repetition of code, everytime that we add/modify a service contract/data contract/message contract we need to re-generate the proxy for the client.
When to use ChannelFactory
The other option is using the ChannelFactory class to construct a channel between the client and the service without the need of a proxy . In some cases, you may have a service that is tightly bound to the client application. In such a case, it makes sense to reference the Interface DLL directly and use ChannelFactory to call your methods using that. One significant advantage of the ChannelFactory route is that it gives you access to methods that wouldn't otherwise be available if you used svcutil.exe..
When to use a ChannelFactory vs Proxy class?
A DLL is helpful if the client code is under you control and you'd like to share more than just the service contract with the client -- such as some utility methods associated with entities and make the client & the service code more tightly bound. If you know that your entities will not change much and the client code is less, then a DLL would work better than a proxy. If the client to your service is external to the system, such as API, it makes sense to use a proxy, because it makes sharing the contract easier by giving a code file rather than a DLL.
In case of NetNamedPipeBinding
It's recommended to use ChannelFactory for the following two reasons:
The easy of use.
avoiding the proxy layer means extra performance.
Channel Factory and Service Proxy are equal features for getting one aim - consume you service. Usually if you control service contract interface both on you client and server, you'd better use ChannelFactory, because it is managed more easier. If you manage only client part - Proxy is a way to go, because othewise you would not be able to control the changes, made on the server side. Besides Proxy gives you a nice tool of generating async methods for your service :)
Some of my apps grab data from the internet. I'm getting into the habit of writing unit tests, and I suspect that if I write a test for values returned from the internet, I will run into latency and/or reliability problems.
What's a valid way to test data that "lies on the other end of a web request"?
I'm using the stock unit testing toolkit that comes with Xcode, but the question theoretically applies to any testing framework.
Unit test is focused specifically on the business logic of your class. There would no latency, reliability etc as you would use some mock object to simulate what you actually interact.
What you are describing is some form of integration testing and for the OP seems like is not what you intent.
You should "obscure" the other end by mocking and not really access the network, a remote database etc.
Among others:
introduce artificial latency in requests
use another machine on the same network or at least another VM
test connection failures (either by connecting to a non existent server or cutting physically the connection
test for incomplete data (connection could be cut half way)
test for duplicate data (app could try to submit the request more than once if it thinks it was not successful - and in some scenarios may lead to lost data)
All of these should fail gracefully (either on the server side or on the client side)
I posed this question to the venerable folks on #macdev IRC channel on freenode.net, and I got a few really good answers.
Mike Ash (of mikeash.com) suggests implementing a local web server inside my app. For complex cases, I'd probably do this. However, I'm just using some of the built in initWithContentsOfURL:(NSURL *)url method of NSData.
For simpler cases, mike says an alternate method is to pass base64 encoded dummy data directly to the NSData initializer. (Use data://dummyDataEncodedAsBase64GoesAfterTheDataProtocolThingy.)
Similarly, "alistra" suggests using local file URLs that point to files containing mock data.
It is common for WSDL generated by Java to contain multiple function definitions with the same function name, differing only by argument type or number.
This poses problems when attempting to consume the WSDL from other languages (particularly languages which don't handle overloading well or at all). For example:
Groovy's WSClient fails outright during initialisation:
java.lang.IllegalArgumentException: An operation with name
[{http://example.com/service-v1}overloadedFunction]
already exists in this service
Ruby's wsdlDriver doesn't fail immediately, but only one version of the overloaded function definitions is invokable (the others seem to be unusable).
Assuming I'm unable to modify the service, Is there a good way to handle this? Perhaps an option on these SOAP client libraries, different libraries, or a well-established transform of the WSDL?
Genesis/Restatement of the problem:
The issue is the generation of consumer side proxies for communicating with a Web Service over SOAP, where the WSDL is not using WS-I Basic profile - specifically by exposing operations of the same name under the same PortType.
Addressing the specifically mentioned client generators:
Groovy's WSClient explicitly states for the module overview:
"If you need to quickly consume and/or publish WS-I compliant web services, GroovyWS can help you."
The Ruby language allows for classes to have methods of the same name, but the last one defined is the only one that the runtime will ever execute.
Options:
Create an Intermediary:
Using a language that (easily) supports the creation of client proxies for overloaded PortType Operations, create a new web service which exposes the services in a WS-I Basic Profile compataible manner, and proxies the requests back up to the original service. This is a manifestation of the Adapter pattern.
Pros: This adapter will serve any consumer capable of generating proxies for WS-I Basic Profile compliant WSDLs. Also, if the Provider service changes you may be able to change the intermediary service without changing the service interfaces it provides to your consuming programs.
Cons: You will need to set up your own server for the web services.
Change the Generated Code:
This is a great solution for the Ruby wsdlDriver issue, since the proxy generator successfully generates a proxy method per operation. All you need to do is change the method names in the Ruby class to be unique.
Pros: Very easy.
Cons: Only applies to a subset of client generators, such as Ruby's wsdlDriver. Also, the proxies will have to be edited every time they are regenerated.
Give the client generators an altered WSDL:
Download the WSDL and manually change it to expose only the definition of the operation that you want, or rename the operations so they have unique names (change MyOp, MyOp, MyOp -> MyOp1, MyOp2, MyOp3). You will almost certainly need to alter the generated code.
Pros: Simplicity.
Cons: If you have a large or ever changing number of WSDL documents to process, this can be time consuming. Also, the proxies will have to be edited every time they are regenerated.