I'm currently developing my first load test ever, so please bear with me ~
The load test itself is running a set of unit tests that POST different requests to an HTTP Handler. Depending on which agent the load test is running on, the requests themselves are made against dev/staging environments, and then passed to a downstream service that 'handles' the request, and executes INSERT statements against a couple of databases. I wanted to build and include a simple plugin that implements ILoadTestPlugin and provides it's own set of instructions for the LoadTestCompleted event handler. This plugin is currently contained within a separate Class Library project that is included in the same solution that is housing the load test itself.
Before I get into describing the problem, I'd like to point out that I am currently running the load test locally against the same handler that I've set up in IIS.
I'm running into an issue when the event fires, and my method attempts to establish an entity connection to the target database context (currently using Entity Framework 4). It appears that the plugin code is failing to find the app.config contained within the load test project. The exception message / stack trace points out that the connection string is invalid, but I have a hankering that the issue is that it cannot find it. On top of that, this same connection string is used throughout our code base in numerous places.
I can rule out the chance of my connection strings being invalid, because if I create a simple unit test method that uses the same configuration file to execute the same code, it works just fine. This is a given because the load test agent is contained in a different directory than that of the project, so it isn't having a problem locating the config file.
I've also tried adding the configuration file copied to the start-up project's output directory as a deployment item in my .testsettings file. No bueno. I've also created an app config file in the plug-in project that is an exact copy of that which I'm trying to use to see if that worked. Still no bueno.
Has anyone run into this problem? If you're trying to use <connectionString> sections in your config file, how can you get the load test plugin to find/use them?
I was going to attempt to use reflection and the good ole' ConfigurationManager to try and make a call into the assembly to find the path (and ultimately, the ProjectName.dll.config file), but wanted to ask the pros on StackOverflow for a little advice before moving forward.
Also, I'd provide code examples if this weren't such straight-forward EF code (or if it was getting past the point of: var dbContext = new dbContext( myConnectionString ); )
Any help / feedback is much appreciated.
Although I did not figure out how to use the application's configuration file within the load test plugin, because the load test & any corresponding plugin(s) run in the QTAgent.exe directory, I was able to implement my post-load test Database clean-up step in two ways.
Using Context Parameters that contained the unique elements of the connection string based on the environment (Run Setting), such that the unique elements of connection string itself (e.g. - DataSource, etc...) were programatically available to my plug-in.
In my Unit Test class that issued requests against the endpoint, I created a static method which was flagged with the [ClassCleanup] attribute. This gets executed when the Test Mix containing unit tests from that class are finished running. The test class is contained within the project's out directory and has access to the app's .config file with the entity connection string:
[TestClass]
public class MyEndpointUnitTests()
{
[TestMethod]
public void SubmitRequestType1()
{
//DoStuff for request type 1
}
[TestMethod]
public void SubmitRequestType2()
{
//DoStuff for request type 2
}
[ClassCleanup]
public static void Cleanup()
{
EndpointLoadTestCleanup.DoCleanup( dbContext = new DbContext( ) );
}
}
You can create a custom Load Test Plug-in, in Initialize method you can grab the connection string from some xml/app.config file add it into context object will use it in your unit test project. it will be more robust and easy to maintain down the road.
Related
My team is building an API which interfaces with another API with many endpoints. Our app is in .net core, so we've been using the connected services wizard for each reference. This means we had to specify the URI's for our endpoints.
Everything is working as expected, but when we move out of dev/qa to staging, all of those references will be wrong, and I will have to manually switch the connected service url's (I think I can do this by simply accessing the ConnectedService.json for each reference and changing extended data: inputs: "[url]" to the different url, but that would mean changing ~20 (so far) references every time we change environments.
My boss says it will become unmanageable as the scope widens. Is there a way to implement dependency injection for service reference uri's so that when the env changes, I can change the reference automatically in code? (I will have the references base url saved in appsettings.json so we can change it without recompiling, because the base url is shared by all of the services, and the wsdl name at the end of it stays the same for each reference across environments.)
The reason I'm asking this as a new question is because, for one, there is limited help on the .net core implementation of service references with the wizard. Most solutions I've found are from 10-15 years ago and it took me a day to realize that those solutions don't apply. An example of a relevant solution is found here: Changing WCF Reference Url .Net Core, however, I don't understand the proposed solution at all.
In the solution, the OP says that adding the code var client = new GetUrlContractClient(new BasicHttpBinding(), new Endpoint("https://someurl/v3/GetUrl-Prod.svc"); solved the problem of updating the uri. My question is, where does this code live, and what is this client object? When I make a call to the API we're referencing, I create a new object asynchronously, there is no reference to some pre existing variable like client above... Did we already have to implement this somewhere and I'm just not seeing it? And what even is this GetUrlContractClient that is being called? I don't understand where the OP is using this if they set up the reference using the wizard.
[Edit] I should say that I also found that implementing the partial method "ConfigureEndpoint" to extend the auto generated code is the "preferred solution," as seen here load WCF service by environment in .net core project. When I try my best to do this for one of the references, it throws a security exception. If this is the way to do it, then I will devote my time to solving that error. However, this solution involves extending the ConfigureEndpoint for every reference, so I would have to do it upwards of 15 times, so it didn't seem to me that it would be the solution. Maybe this is what the OP for the referenced question was doing, but if so I do not see the connection. They seem to be completely different solutions.
It seems like this would be a relatively straight forward thing to lookup and solve with what we've already implemented, but I have had no luck. Anytime I find something, the answer is vague-ish like above and I don't see how it applies to my situation. How can I change the uri's for my web service references that are set up with the web service reference wizard?
Extending ConfigureEndpoint for each connected service works. The path cannot not include the ?wsdl at the end. The extension code (for one of my files) is below.
public partial class CreateOrderPortTypeClient
{
const string uriSuffix = "(last part of URI without ?wsdl)";
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials)
{
EndpointCreator.SetServiceEndpointAddress(serviceEndpoint, uriSuffix);
}
}
I also added a class EndpointCreator which handles the base address, like so.
public class EndpointCreator
{
static string uriBase;
public static void GenerateBaseAddress(string uriBase)
{
EndpointCreator.uriBase = uriBase;
}
public static void SetServiceEndpointAddress(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, string uriSuffix)
{
serviceEndpoint.Address =
new System.ServiceModel.EndpointAddress(new System.Uri(uriBase + uriSuffix),
new System.ServiceModel.DnsEndpointIdentity(""));
}
}
I assigned the uriBase in startup by accessing the config. While I had to extend each one individually, its actually very manageable because this is a small thing to do when adding a new service through the wizard.
I've recently had to migrate to the C# world. Coming from the Java land, I could add a public static void main(String[] args) method to any class and select to run that class from Eclipse/Netbeans for any code/logic that I wanted to quickly test.
Is there an equivalent of the same capability in C#.Net/Visual Studio? I've tried doing that and the best I can do is to execute it from the command prompt via csc.exe. However, for some reason, it complains about not finding the relevant DLLs - it seems to expect to run that class in complete isolation without any dependency on "external code" (i.e., code residing in that VS project/solution where the class resides).
Reason for this capability: All project files are marked as class libraries and sometimes I just wish to check if a particular set of methods/data/logic will work as expected with the current code base. In Java, I'd quickly write it in the main method and execute that class to see how it goes prior to committing it to version control. However, there seems to be no easy way to trigger the execution of "my class" with all dependencies correctly handled by csc.exe
Current Solution: Add this testing code to the unit test project and select to execute that particular "test" so as to check if the idea seems to work fine (it may fire DB calls or webservice class etc., and not be purely a logical flow of computation). This seems to work fine and is my current way of doing things. I was wondering if the Main method was even possible/recommended.
Question: Is this even possible with C#/VS or not recommended?
Update: I can't add a console project just to achieve this since the addition of projects is tightly controlled by the source control team. Hence the question of the Main method 'hack' for quick and dirty checks/tests.
Your project type needs to be Console Application for it to "recognize" a Program.Main method, not Class Library. The intent is for a Class Library to be an encapsulated grouping of functionality that can only be accessed by a project that is set up to allow for user input. Those can be a Console Application, Web project (MVC/API), or Desktop (WPF).
If you just want to execute a test against the code within a Class Library project, you can also create a Unit Test project, add a reference and execute very explicit tests against the functionality you're looking to achieve.
You can find out the differences between the different project types by examining the .csproj files in your favorite text editor.
In Visual Studio go New->Project then select Console Application (in Windows\Classic Desktop in VS2015). This gives you a basic console application with...
static void Main(string[] args)
{
}
setup and ready to go. However for simply trying out code you may find this cumbersome (creating a new project and folder just to test code) and for testing code (that doesn't rely on existing libraries) you could use something like .NET Fiddle...
https://dotnetfiddle.net/
Where you can quickly create and test code there and run it via the browser.
I have an NUnit test project that is testing a Console App project. The Console app project uses the app.config file heavily. When running tests from my NUnit test project, the code being tested uses the config values in my Tests.dll.config file. This file is located in my Test project's root directory and is a copy of the app.config file from the app being tested.
However, in some tests I need to change the value of some of the config settings. I have been using this in my Nunit test to do it:
ConfigurationManager.AppSettings.Set("SettingKey" , "SettingValue");
I don't want these runtime config changes I make in one test to interfere or be seen by any other tests. Is this the correct way to do it?
UPDATE
I should also mention that my tests run in parallel. I think this is because I am using Re-sharper.
So if I change the config in one test I think it may change the config in another test, which I don't want.
Is it possible to wrap code reading configuration in a interface?
For example:
public interface IAppSettings
{
string Get(string settingKey);
}
So you can easily abstract from the app.settings file.
Then in your NUnit project you can implement IAppSettings by a simple class and configure your app to use it. In that case you don't need to read a real app.config file and can easily change configuration. It will also speed up your tests.
It seems you are interested in an integration test and not a unit test. The reason being that your tests need to access the configuration file modify some values so your tests can run correctly.
You said you don't want your runtime config changes to interfere with other tests.
The best way to handly this is to use NUnit built-in test initialize and tear-down approach.
For example, you can use
A. NUnit [setup] attribute make runtime changes to your config
B. NUnit [teardown] attribute rollback the changes you did
See more info
http://www.nunit.org/index.php?p=setup&r=2.2.10
Note each that each and every test in your class would run the above setup/teardown sequence.
So if you need more customized approach, you can simply create your own setup method and call it from the test you need after ther assert call a tear-down method to clean-up/rollback what you did in your setup method. This way it's only affecting for the tests you need it to change config values.
For example (in pseudo code)
Public void Mytestmethod()
Call my own test init
Call SUT
Perform Any asserts
Call My own tear down
I have a Winform app that has 16 SQL Connections currently stored in the DAL Projects Settings.settings.
I am trying to write a "Manager" class to simplify this(like here). However, most of the examples I find on the web seem to use ConfigurationSettings.AppSettings["something"]. While, I WAS using Properties.Settings.Default.something.
Can someone, please, explain which is considered CORRECT and why for a Desktop applications?
I think the correct way is to use the app.config file and store them in the connectionStrings section?
Then you can access them like:
ConfigurationManager.ConnectionStrings["something"].ConnectionString
You could write a wrapper around that easily if that is too "ugly".
public class ConnectionManager
{
public string Something
{
get
{
// TODO: check to make sure the configuration exists and throw an exception perhaps
return ConfigurationManager.ConnectionStrings["something"].ConnectionString;
}
}
}
Oops...as pointed out I meant to do ConfigurationManager and not ConfigurationSettings.
I've never been a big fan of putting sql connection strings into configuration files for software. Users have a habit of goofing them up out of curiosity or stupidity (or some combination of the two). I like to put all of my connection strings (development, model, production, whatever) into the Properties of my data access library, and include within it a ConfigurationSettings class that I use to access them based on some property that is set by the consuming application:
public class ConfigurationSettings
{
public static string MyConnectionString
{
get
if(ConfigurationSettings.TestMode)
return Properties.Settings.Default.MyConnectionStringTest;
else
return Properties.Settings.Default.MyConnectionStringProd;
}
}
// I typically only have test and not-test. This could
// easily be some other combination of values to satisfy
// multiple environments.
public static bool TestMode { get; private set;}
}
This allows me to call the static properties of this class through a common name and have all connection strings available depending on some criteria. This gets your specific datasets, entities, whatever data model you're using from being in the business of worrying about connection strings and the settings can be compiled into the .dll (and no longer need to worry about them). This method can also be modified to pull settings from an app.config (which I do for ASP.Net sites) in a similar method.
UPDATE: There really is no "correct" way as you imply. The app.config was designed to hold configuration settings that are modifiable without rebuilding the application. Property Settings were designed to hold settings that are not modifiable. So both are perfectly valid. Probably the most "correct" way is a way that makes sense both for your application and for your development team.
We prefer to use Properties.Settings (aka. settings.settings) because it's strongly typed. Don't try to do fancy tricks that have different environments (dev/prod) in the same config file. It is much easier to have a separate config file per environment, and to rename the configs when you deploy them. i.e.
app.config
app.stage.config
app.test.config
app.prod.config
We use PowerShell scripts (batch files on steroids) to do our deployments. I'll simplify what we do as a traditional batch file - (pseudo code/untested sample):
#echo off
:: %1 is the environment name (first parameter)
setlocal
set source=c:\tfs\project\bin\release\
set target=\\server\share\path\
xcopy /s/e %source% %target%
:: Using a copy command to rename/overwrite the env specific version
if exists %target%\app.%1.config copy /y %target%\app.%1.config %target%\app.config
Properties.Settings.Default are generally used to save application internal state like the color of the background, to remember user settings.
ConfigurationSettings is actually the "Manager" class you were talking about and can access other custom sets of settings from the app.config file, including connection strings.
I have an asp.net mvc project that uses some search methods in a seperate library.
This library needs to know the location of my lucene index files.
private static string lucenePath = ConfigurationManager.AppSettings["lucenePath"];
public static ColorList SearchColors(Query query) {
return new ColorList(
new IndexSearcher(Path.GetFullPath(lucenePath)),
query);
}
This correctly reads my configured lucenePath from the web.config's application key node.
But how can I get the correct full path from this relative path? Path.GetFullPath gives me a completely incorrect path.
--Conclusion--
If you want to go full-out, tvanfosson's answer is probably for you.
I, however, kept it a little more brain dead by using the following:
Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
ConfigurationManager.AppSettings["luceneIndex"].TrimStart('\\'));
This will look in the caller's app.config for an appkey called "path" and combine its value to the caller's path. The TrimStart() makes sure that the config file can both contain a leading \ or not.
Server.MapPath(string);
Since you are referencing this from a separate library, you might have to jump through a bunch of hoops to get access to the HttpServerUtitity or introduce some coupling to classes that are difficult to mock. You might want to consider having a single configuration class that loads properties from the web configuration that gets injected into your library via constructor/setter. To make it easier to test against, you could define an interface that could be mocked in your unit tests and have it implement that. The configuration class could use the HttpServerUtility to obtain the absolute path and store it internally to be reused.