Using NUnit-2.5 RequiresSTAAttribute with TeamCity 4 - msbuild

Using TeamCity, I'm trying to get a (TestAutomationFX) test that requires an STA thread to run .
It works via a custom app.config that configures NUnit 2.4.x (8) (as referred to by Gishu, thanks, described at http://madcoderspeak.blogspot.com/2008/12/getting-nunit-to-go-all-sta.html)
It works via:
/// <summary>
/// Via Peter Provost / http://www.hedgate.net/articles/2007/01/08/instantiating-a-wpf-control-from-an-nunit-test/
/// </summary>
public static class CrossThreadTestRunner // To be replaced with (RequiresSTA) from NUnit 2.5
{
public static void RunInSTA(Action userDelegate)
{
Exception lastException = null;
Thread thread = new Thread(delegate()
{
try
{
userDelegate();
}
catch (Exception e)
{
lastException = e;
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
if (lastException != null)
ThrowExceptionPreservingStack(lastException);
}
[ReflectionPermission(SecurityAction.Demand)]
static void ThrowExceptionPreservingStack(Exception exception)
{
FieldInfo remoteStackTraceString = typeof(Exception).GetField(
"_remoteStackTraceString",
BindingFlags.Instance | BindingFlags.NonPublic);
remoteStackTraceString.SetValue(exception, exception.StackTrace + Environment.NewLine);
throw exception;
}
}
I'm hoping to use something built in. So NUnit 2.5.0.8322 (Beta 1)'s RequiresSTAAttribute seems ideal. It works standalone, but not via TeamCity, even when I attempt to force the issue via:
<NUnit Assemblies="Test\bin\$(Configuration)\Test.exe" NUnitVersion="NUnit-2.5.0" />
The docs say the runner supports 2.5.0 alpha 4? (http://www.jetbrains.net/confluence/display/TCD4/NUnit+for+MSBuild)
Probably answering my own question, 2.5.0 Aplha 4 doesnt have RequiresSTAAttribute, hence the runner is not honouring my Attribute...

TeamCity 4.0.1 contains NUnit 2.5.0 beta 2. I believe that should work for that case.

Can you see if this helps? Setting STA via the .config file approach... as in pre NUnit 2.5
http://madcoderspeak.blogspot.com/2008/12/getting-nunit-to-go-all-sta.html

For now, I'm using:
private void ForceSTAIfNecessary(ThreadStart threadStart)
{
if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
threadStart();
else
CrossThreadTestRunner.RunInSTA(threadStart);
}
[Test]
public void TestRunApp()
{
ForceSTAIfNecessary(TestRunAppSTA);
}
public void TestRunAppSTA()
{
Assert.That(Thread.CurrentThread.GetApartmentState(), Is.EqualTo(ApartmentState.STA));
...
}
instead of:
[RequiresSTA]
public void TestRunAppSTA()
{
Assert.That(Thread.CurrentThread.GetApartmentState(), Is.EqualTo(ApartmentState.STA));
...
}

Related

Is it possible to add completion items to a Microsoft Language Server in runtime?

I am trying to develop a IntelliJ plugin which provides a Language Server with help of lsp4intellij by ballerina.
Thing is, i've got a special condition: The list of completion items should be editable in runtime.
But I've not found any way to communicate new completionItems to the LanguageServer process once its running.
My current idea is to add an action to the plugin which builds a new jar and then restarts the server with the new jar, using the Java Compiler API.
The problem with that is, i need to get the source code from the plugin project including the gradle dependencies accessable from the running plugin... any ideas?
If your requirement is to modify the completion items (coming from the language server) before displaying them in the IntelliJ UI, you can do that by implementing the LSP4IntelliJ's
LSPExtensionManager in your plugin.
Currently, we do not have proper documentation for the LSP4IntelliJ's extension points but you can refer to our Ballerina IntelliJ plugin as a reference implementation, where it has implemented Ballerina LSP Extension manager to override/modify completion items at the client runtime in here.
For those who might stumble upon this - it is indeed possible to change the amount of CompletionItems the LanguageServer can provide during runtime.
I simply edited the TextDocumentService.java (the library I used is LSP4J).
It works like this:
The main function of the LanguageServer needs to be started with an additional argument, which is the path to the config file in which you define the CompletionItems.
Being called from LSP4IntelliJ it would look like this:
String[] command = new String[]{"java", "-jar",
"path\\to\\LangServer.jar", "path\\to\\config.json"};
IntellijLanguageClient.addServerDefinition(new RawCommandServerDefinition("md,java", command));
The path String will then be passed through to the Constructor of your CustomTextDocumentServer.java, which will parse the config.json in a new Timer thread.
An Example:
public class CustomTextDocumentService implements TextDocumentService {
private List<CompletionItem> providedItems;
private String pathToConfig;
public CustomTextDocumentService(String pathToConfig) {
this.pathToConfig = pathToConfig;
Timer timer = new Timer();
timer.schedule(new ReloadCompletionItemsTask(), 0, 10000);
loadCompletionItems();
}
#Override
public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(CompletionParams completionParams) {
return CompletableFuture.supplyAsync(() -> {
List<CompletionItem> completionItems;
completionItems = this.providedItems;
// Return the list of completion items.
return Either.forLeft(completionItems);
});
}
#Override
public void didOpen(DidOpenTextDocumentParams didOpenTextDocumentParams) {
}
#Override
public void didChange(DidChangeTextDocumentParams didChangeTextDocumentParams) {
}
#Override
public void didClose(DidCloseTextDocumentParams didCloseTextDocumentParams) {
}
#Override
public void didSave(DidSaveTextDocumentParams didSaveTextDocumentParams) {
}
private void loadCompletionItems() {
providedItems = new ArrayList<>();
CustomParser = new CustomParser(pathToConfig);
ArrayList<String> variables = customParser.getTheParsedItems();
for(String variable : variables) {
String itemTxt = "$" + variable + "$";
CompletionItem completionItem = new CompletionItem();
completionItem.setInsertText(itemTxt);
completionItem.setLabel(itemTxt);
completionItem.setKind(CompletionItemKind.Snippet);
completionItem.setDetail("CompletionItem");
providedItems.add(completionItem);
}
}
class ReloadCompletionItemsTask extends TimerTask {
#Override
public void run() {
loadCompletionItems();
}
}
}

JAX-RS Response.getEntity() always null

I need help with Arquillian test.
Add code example of situation.
This code is working ok in real environment. Only in test case made with arquillian the result is not expected
The code:
#Stateless
public class CustomerResourceImpl implements CustomerResource{
#Override
public Response findOne(String id) {
String res = "Un cliente";
return Response.ok(res).build();
}
}
#Path("customer")
#Produces(MediaType.APPLICATION_JSON)
public interface CustomerResource {
#GET
#Path("/findOne")
public javax.ws.rs.core.Response findOne(#QueryParam("id") String id);
}
And this test case
#RunWith(Arquillian.class)
public class CustomerResourceTest {
#Deployment (testable = false)
public static Archive createTestArchive() {
return ShrinkWrap
..... (mas)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
#ArquillianResource
private URL deploymentURL;
#Test
#RunAsClient
public void findOne(#ArquillianResteasyResource CustomerResource resource) throws Exception {
final Response response = resource.findOne("1");
System.out.println(response.getEntity()); // IS NULL ??
System.out.println(response.getStatus()); // 200 OK
assertNotNull(response);
}
}
The problem is that response.getEntity() is always NULL . Why? The status response OK = 200 , it is OK. This service run ok in jboss 7.2 with Java 8.
Thanks!
The reason is #Deployment (testable = false)
#Deployment says:
testable = Defines if this deployment should be wrapped up based on the protocol so the testcase can be executed incontainer.
So false means it will not be deployed in the container, and therefore will be null when your tests run inside the container.
I recommend using #Deployment with not parameters passed in rather than setting testable = true
I just solved this today after a days of fiddling. I think I pasted the #Deployment (testable = false) code from examples on the internet that I didn't understand hoping to get something working.

Toggling App.Config settings at runtime C#

I am wondering what the best approach to toggling App.Config settings for C# would be. This is involving our test suite, and we would like the option to either choose a remote or local environment to kick the tests off. We use LeanFT and NUnit as our testing framework, and currently in order to get tests to run remote we have to add an <leanft></leanft> config in the App.config file. How can I specify different configurations at run time when I kick these tests off thru the command line? Thanks!
Any leanft configuration can be modified at runtime, by using the SDK namespace or the Report namespace.
Here's an example using NUnit 3 showing how you can achieve this
using NUnit.Framework;
using HP.LFT.SDK;
using HP.LFT.Report;
using System;
namespace LeanFtTestProject
{
[TestFixture]
public class LeanFtTest
{
[OneTimeSetUp]
public void TestFixtureSetUp()
{
// Initialize the SDK
SDK.Init(new SdkConfiguration()
{
AutoLaunch = true,
ConnectTimeoutSeconds = 20,
Mode = SDKMode.Replay,
ResponseTimeoutSeconds = 20,
ServerAddress = new Uri("ws://127.0.0.1:5095") // local or remote, decide at runtime
});
// Initialize the Reporter (if you want to use it, ofc)
Reporter.Init(new ReportConfiguration()
{
Title = "The Report title",
Description = "The report description",
ReportFolder = "RunResults",
IsOverrideExisting = true,
TargetDirectory = "", // which means the current parent directory
ReportLevel = ReportLevel.All,
SnapshotsLevel = CaptureLevel.All
});
}
[SetUp]
public void SetUp()
{
// Before each test
}
[Test]
public void Test()
{
Reporter.ReportEvent("Doing something", "Description");
}
[TearDown]
public void TearDown()
{
// Clean up after each test
}
[OneTimeTearDown]
public void TestFixtureTearDown()
{
// If you used the reporter, invoke this at the end of the tests
Reporter.GenerateReport();
// And perform this cleanup as the last leanft step
SDK.Cleanup();
}
}
}

How to add RequestInterceptor and change Referer in BrowserMob-Proxy 2.0

I am using BrowserMob-Proxy inside a Selenium test suite. I would like to change the Referer for a few tests. I have added requestInterceptor from the 2.0 docs into our MyProxy class and while it does not generate an error the Referer is not changed.
For now, I am trying to get the requestInterceptor to work in the MyProxy class where the proxy is created. In the end, I would like to be able to specify the Referer in each test.
If anyone has suggestions on getting the requestInterceptor to work please let me know. Here is the MyProxy class. Please let me know if other code examples would be helpful to troubleshoot this.
import org.openqa.selenium.Proxy;
import net.lightbody.bmp.core.har.Har;
import net.lightbody.bmp.proxy.ProxyServer;
import net.lightbody.bmp.proxy.http.BrowserMobHttpRequest;
import net.lightbody.bmp.proxy.http.RequestInterceptor;
public class MyProxy {
private ProxyServer proxy;
private boolean initialized;
public Har endCapture() throws Exception {
Thread.sleep(15000);
return this.proxy.getHar();
}
public Proxy getSeleniumProxy() {
return this.proxy.seleniumProxy();
}
public boolean isInitialized() throws Exception {
return this.initialized;
}
public void start() throws Exception {
int proxyPort = Integer.parseInt(System.getProperty("proxyPort"));
this.proxy = new ProxyServer(proxyPort);
this.proxy.start();
this.proxy.setCaptureHeaders(true);
this.proxy.setCaptureContent(true);
this.proxy.addRequestInterceptor(new RequestInterceptor() {
#Override
public void process(BrowserMobHttpRequest request, Har har) {
request.getMethod().removeHeaders("Referer");
request.getMethod().addHeader("Referer", "http://www.google.com");
}
});
this.initialized = true;
}
public void startCapture() throws Exception{
this.proxy.newHar("MyHar");
}
public void stop() throws Exception {
this.proxy.stop();
this.initialized = false;
}
}
I think the key here is how to test the newly-added header, which is tricky to do manually.
I chose as a test-site: http://headers.cloxy.net/request.php, which simply logs the names and values of all request headers. Having first set up my proxy, I arranged a screenshot to be written after page request completed.
I was able to determine that:
#Override
public void process(BrowserMobHttpRequest req, Har har) {
req.getMethod().removeHeaders("Referer");
req.getMethod().addHeader("Referer", "http://www.google.xyz");
// Some extras
req.getMethod().addHeader("Foo_" + System.currentTimeMillis(), "Bar_" + new java.util.Date());
req.getMethod().setHeader("Lorem_" + System.currentTimeMillis(), "Ipsum_" + new java.util.Date());
}
... successfully adds all the specified headers in both BrowserMob 2.0.0 and 2.1 beta 5. I've confirmed this for each version in Firefox (45), Chrome (49), and PhantomJS.
So, in short:
The OP's header-adding syntax is perfectly fine.
setHeader also works as expected.
BMP version numbers do not affect this (but by all means upgrade to 2.1 as/when it is released)
Browsers do not affect this
Review this issue and see if it describes your problem.
Suggestion is to move to the latest version of BrowserMobProxy which is 2.1.0-beta-5.

New MVC 4 Beta Web API is not serving requests when ran as a Windows Service

I'm trying to run a self hosted executable as a Windows service. I'm using the MVC 4 beta Web API. First I used Derik Whittaker's blog for setting up the basic console application and tested it with positive results.
I then used Einar Egilsson's blog to make it work as both a console application and a windows service. The application installed as a service just fine. I set the service logon to use my own for this basic testing; it failed to bind to the socket without this. When the service starts up I see all my trace logs as expected there are no fatal errors. The application appears to be running normally. When I test using fiddler using the same request for the console application I get a "HTTP/1.1 500 Internal Server Error".
Using this same code when I turn off the service then launch using F5 in VS the application starts up just fine and serves the same request!? The log entries are identical within the same execution paths.
public partial class TestService : ServiceBase {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private HttpSelfHostServer _server;
static void Main(string[] args) {
Logger.Debug("Main Called");
var service = new TestService();
if (Environment.UserInteractive) {
Logger.Debug("Environment.UserInteractive == true");
Console.WriteLine("Press any key to stop program");
service.OnStart(args);
service.OnStop();
} else {
Logger.Debug("Environment.UserInteractive == false");
try {
Run(service);
} catch(Exception exception) {
Logger.Fatal(exception.Message, exception);
}
}
}
protected override void OnStart(string[] args) {
Logger.Debug("OnStart called");
var hostUri = string.Format("http://{0}:{1}", Environment.MachineName, ConfigurationManager.AppSettings["Service.Port"]);
Logger.Debug("URL:" + hostUri);
var selfHostConfiguration = new HttpSelfHostConfiguration(hostUri);
selfHostConfiguration.Routes.MapHttpRoute(
name: "DefaultApiRoute",
routeTemplate: "endpoints/{controller}",
defaults: null
);
Logger.Debug("Routes registered");
try {
using (_server = new HttpSelfHostServer(selfHostConfiguration)) {
Logger.Debug("Hosting at " + hostUri + "/endpoints/{controller}");
_server.OpenAsync().Wait();
if (Environment.UserInteractive) { // *** I've tried this commented out as well
Console.ReadLine();
}
Logger.Debug("End of using");
}
} catch(Exception exception) {
Logger.Fatal(exception.Message, exception);
if(exception.InnerException != null) {
Logger.Fatal(exception.InnerException.Message, exception.InnerException);
}
}
}
protected override void OnStop() {
_server.Dispose();
}
}
It has been some time since you posted this but I wanted to input.
I don't know why this is, but the internal error comes from initializing the self host inside the onStart method. You must initialize it in the constructor of the service and then only call the _server.OpenAsync() in the onStart method.
Or at least that is what worked for me.
Use TopShelf. I just blogged about how to do that.
as i can see, you use _server.OpenAsync().Wait(); in OnStart method. This just makes your initialization code to freeze, all code after that line will not execute. To avoid this try to remove .Wait() from the OpenAsync().