EiffelStudio finalize with contracts enabled - eiffel

How to produce the Finalized executable with contract checking enabled? It is possible to keep the check statements intact, but can we keep all the pre/postconditions and class invariants?
I need this for testing a computationally expensive application and frozen with contracts executable is a bit too slow in my case.

The IDE shows a dialog on request for finalization that asks whether the assertions should be kept in the generated executable. The dialog is discardable. If you select the checkbox "Do not ask me again", the assertions will NOT be generated and the IDE will NOT show this dialog anymore. You can reset this selection by going to the Parameters (e.g., from the main menu: Tools | Parameters), and restoring the default value for the finalization dialog under Interface | Dialogs.
In the command line, the compiler accepts an option -keep right after -finalize. It tells the compiler to keep assertions when finalizing the executable.
Both the IDE and the compiler pick the settings which assertions should be generated from the project settings. You can specify them for every group (system/library/cluster) and every class individually.
Edit. Here is a minimal example with 2 files:
example.e:
class EXAMPLE create make feature
make
local
n: INTEGER
do
if n = 0 then f
elseif n = 1 then g
end
rescue
n := n + 1
print ({EXCEPTIONS}.tag_name)
retry
end
f require pre: out = "x" do end
g do ensure post: out = "x" end
end
example.ecf:
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-21-0" name="example">
<target name="example">
<root class="EXAMPLE" feature="make"/>
<option>
<assertions precondition="true" postcondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<cluster name="test" location="."/>
</target>
</system>
Compilation with the options -finalize -keep -config example.ecf -c_compile produces an executable that prints prepost.

Related

Batch copy the list of items using MSBuild Task RoboCopy

There are list of source and destinations directories defined in . I need a single task/target to perform the robocopy as per the defined item group properties.
<ItemGroup>
<ItemToCopy Include="$(RootPath)\Audi">
<WhereToCopy>$(FinalFolder)\Audi</WhereToCopy>
<WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Custom">
<WhereToCopy>$(FinalFolder)\Custom</WhereToCopy>
<WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Audi\bin">
<WhereToCopy>$(FinalFolder)\Audi\bin</WhereToCopy>
<WhatToCopy>*.*</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Custom\bin">
<WhereToCopy>$(FinalFolder)\Custom\bin</WhereToCopy>
<WhatToCopy>*.*</WhatToCopy>
</ItemToCopy>
I have tried following code, expecting to perform copy operation for each Items in the deployment folder.
<Target Name="CopyAll">
<RoboCopy
Source="#(ItemToCopy)"
Destination="%(ItemToCopy.WhereToCopy)" Files="ItemtoCopy.Whattocopy"/>
</Target>
In addition, If we see the items 1 & 2 (also 3 & 4), they are same in the sense of copying similar kinds of files from their %ItemName to same path with subdirectory %ItemName. It could be great if we could also avoid that extra code smell.
Hoping something like below to work:
<ItemToCopy Include="$(RootPath)\#PublishProjects">
<WhereToCopy>$(FinalFolder)\#PublishProjects</WhereToCopy>
<WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
where,
<ItemGroup>
<PublishProjects Include="Audi" />
<PublishProjects Include="Custom" />
</ItemGroup>
You can't mix # and %. Both of those indicate an operation on an item group. Using % performs the operation once for each item in the item group. # performs the operation once upon the entire item group. Note that not all tasks support item groups.
If you use # then you're using a "transform" which has a funky syntax.
https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-transforms
Also, item groups are intended to match files for you. Specifying folders does work and it refers to the folder, but one of msbuild's strengths is in finding the files for you.
Instead of
<ItemToCopy Include="$(RootPath)\Audi">
<WhereToCopy>$(FinalFolder)\Audi</WhereToCopy>
<WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
I'd go with
<ItemToCopy Include="$(RootPath)Audi\*.svc">
<TargetSubDir>Audi\</TargetSubDir>
</ItemToCopy>
Then your target would be more like
<Target Name="CopyFiles">
<Copy Condition="#(ItemToCopy)!=''"
SourceFiles="#(ItemToCopy)"
DestinationFiles="#(ItemToCopy->'$(FinalFolder)%(TargetSubDir)%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="true" />
</Target>
Remember, it is an msbuild convention that all properties/metadata representing a directory include the trailing slash.
Ok, that answer I gave skips the usage of robocopy which I acknowledge is a specific part of your question.
The # and % still holds true (you can't mix their usage) and that's mostly where you've gone wrong in your CopyAll target.
<Target Name="CopyAll">
<RoboCopy
Source="#(ItemToCopy)"
Destination="#(ItemToCopy->'%(WhereToCopy)')" Files="#(ItemtoCopy->'%(Whattocopy)')"/>
</Target>
Check out the help on transforms for a better understanding of how to use them
https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-transforms

Codename One - tests.dat file needed when using build.unitTest=1

I created a test extending the AbstractTest class. The test works correctly in Netbeans: I right-click on the project name, then on "Test". Of course the Netbeans test in done in the Codename One Simulator. I want to repeat the test on several real devices, as I asked in "Codename One - Test Recorder: execute a test on a real device"
So I added the build.unitTest=1 build hint and I checked that my build.xml contains:
<target name="test-for-ios-device" depends="clean,copy-ios-override,copy-libs,compile-test,clean-override">
<codeNameOne
jarFile="${dist.jar}"
displayName="${codename1.displayName}"
packageName = "${codename1.packageName}"
mainClassName = "${codename1.mainName}"
version="${codename1.version}"
icon="${codename1.icon}"
vendor="${codename1.vendor}"
subtitle="${codename1.secondaryTitle}"
buildArgs="build.unitTest=1"
targetType="iphone"
certificate="${codename1.ios.debug.certificate}"
certPassword="${codename1.ios.debug.certificatePassword}"
provisioningProfile="${codename1.ios.debug.provision}"
appid="${codename1.ios.appid}"
automated="${automated}"
/>
</target>
<target name="test-for-android-device" depends="clean,copy-android-override,copy-libs,compile-test,clean-override">
<codeNameOne
jarFile="${dist.jar}"
displayName="${codename1.displayName}"
packageName = "${codename1.packageName}"
mainClassName = "${codename1.mainName}"
version="${codename1.version}"
icon="${codename1.icon}"
vendor="${codename1.vendor}"
subtitle="${codename1.secondaryTitle}"
buildArgs="build.unitTest=1"
targetType="android"
keystoreAlias="${codename1.android.keystoreAlias}"
keystore="${codename1.android.keystore}"
certPassword="${codename1.android.keystorePassword}"
automated="${automated}"
/>
</target>
After that, I sent an iOS build: it doesn't compile. So I tried to send an Android build. The generated apk, on a real device, produces an error because the /tests.dat file is absent. The exact error is: "Test data not found in the file, make sure the ant task was executed in full" (it's produced by DeviceRunner class at line 57). I added an empty tests.dat in /src, but it's not useful, because no test is runned.
I don't know what I have to do.
I need step-by-step instructions to test an app on a real device in the same way that I do in the Codename One Simulator. Thanks.
In the compile-test target which is the base target required we have this line:
<prepareTests classesDir="${build.classes.dir}" testClassesDir="${build.test.classes.dir}" seJar="JavaSE.jar" metaDataFile="${build.test.classes.dir}/tests.dat" />
This should generate a valid tests.dat file for the test directory which should get packaged into the build.

How to retry failed scenario in Behave using python

Can someone please tell me how I can run a failed test again in Behave using Python?
I want to re-run the failed test case automatically if it fails.
The behave library actually has a RerunFormatter which can help you rerun the failing scenarios of your previous test-run. It creates a text file of all your failing scenarios like:
# -- file:rerun.features
# RERUN: Failing scenarios during last test run.
features/auth.feature:10
features/auth.feature:42
features/notifications.feature:67
To use the RerunFormatter all you need to do is put it in your behave configuration file (behave.ini):
# -- file:behave.ini
[behave]
format = rerun
outfiles = rerun_failing.features
To rerun the failing scenarios, use this command:
behave #rerun_failing.features
I know that's a later answer but it could help others.
There is another approach that also could help, it's implementing it under the environment.py file, you could do the retry by a specific tag.
Provides support functionality to retry scenarios a number of times
before their failure is accepted. This functionality can be helpful
when you use behave tests in an unreliable server/network
infrastructure.
For example, I am running tag "#smoke_test" on CI, so I choose this tag to patch with retry condition.
First, on your environment.py import the following:
# -- file: environment.py
from behave.contrib.scenario_autoretry import patch_scenario_with_autoretry
Then add the method:
# -- file:environment.py
#
def before_feature(context, feature):
for scenario in feature.scenarios:
if "smoke_test" in scenario.effective_tags:
patch_scenario_with_autoretry(scenario, max_attempts=3)
*max_attempts are by default set as 3. I just described there to make it explicit that you can actually set how many retries you want.

How can I get AppEngine to log info level only for my app?

So I've tried configuring AppEngine logging according to this guide, ensuring I've configured the logging.properties file to be used in web.xml. I've configured logging.properties the following way:
.level = WARNING
nilsnett.chinese.backend.level = INFO
The package name of my logging wrapper is nilsnett.chinese.backend. The problem is that even with this configuration, info-level log output from my app is filtered. Evidence:
I've also tried the following config, which yielded the same result (including the logger class name at the end of the package name):
.level = WARNING
nilsnett.chinese.backend.JavaUtilLogger.level = INFO
To demonstrate that the logging.properties-file is actually read, and that I actually do write info-level logging data to app-engine in this service call, let me show you what happens when I set.level=INFO:
So my desired result is to have INFO and higher-level log outputs from my packages, while other packages, like org.datanucleus, only shows output if WARNING or more severe. In the example above, I want only the two lines marked with the purple star. Am I doing anything wrong?
change your config to:
.level = WARNING
# Set the default logging level for the datanucleus loggers
DataNucleus.JDO.level=WARNING
DataNucleus.Persistence.level=WARNING
DataNucleus.Cache.level=WARNING
DataNucleus.MetaData.level=WARNING
DataNucleus.General.level=WARNING
DataNucleus.Utility.level=WARNING
DataNucleus.Transaction.level=WARNING
DataNucleus.Datastore.level=WARNING
DataNucleus.ClassLoading.level=WARNING
DataNucleus.Plugin.level=WARNING
DataNucleus.ValueGeneration.level=WARNING
DataNucleus.Enhancer.level=WARNING
DataNucleus.SchemaTool.level=WARNING
# FinalizableReferenceQueue tries to spin up a thread and fails. This
# is inconsequential, so don't scare the user.
com.google.common.base.FinalizableReferenceQueue.level=WARNING
com.google.appengine.repackaged.com.google.common.base.FinalizableReferenceQueue.level=WARNING
this is are coming from logging config template, so to set datanucleus to warning you have todo like in this template.
https://developers.google.com/appengine/docs/java/#Logging
and then just add your own logging config:
nilsnett.chinese.backend.level = INFO
this should solve it

Can I force the installer project to use the .config file from the built solution instead of the original one?

I am using the solution to this question in order to apply configuration changes to App.config in a Winforms project. I also have an installer project for the project that creates an installable *.msi file. The problem is, the config file bundled in the installers is the original, un-transformed config file. So we're not getting the production connection strings in the production installer even though the config file for the built winforms project has all the correct transformations applied.
Is there any way to force the installer project to use the output of project build?
First of all: it is impossible to make the Setup Project point to another app.config file by using the Primary output option. So my solution is going to be a work around. I hope you find it useful in your situation.
Overview:
The basic idea is:
Remove the forced app.config from the Setup Project;
Add a file pointing to the app.config, manually;
Use MSBuild to get into the vdproj file, and change it to match the real output of the transformed app.config.
Some drawbacks are:
The setup project only gets updated, if the project it deploys build. ahhh... not a real drawback!
You need MSBuild 4.0... this can also be worked around!
Need a custom Task, called FileUpdate... it is open source and has installer.
Lets Work:
1) Go to your Setup Project, and select the Primary Output object, right click and go to Properties. There you will find the Exclude Filter... add a filter for *.config, so it will remove the hard-coded app.config.
2) Right click your Setup Project in the Solution Explorer -> Add -> File... select any file that ends with .config.
3) Download MSBuild Community Tasks Project, I recomend the msi installer.
4) Unload your project (the csproj) and replace the code from the other question with this one:
Code:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
<Target Name="AfterCompile" Condition="exists('app.$(Configuration).config')">
<!-- Generate transformed app config in the intermediate directory -->
<TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" />
<!-- Force build process to use the transformed configuration file from now on. -->
<ItemGroup>
<AppConfigWithTargetPath Remove="app.config" />
<AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
<PropertyGroup>
<SetupProjectPath>$(MSBuildProjectDirectory)\$(IntermediateOutputPath)$(TargetFileName).config</SetupProjectPath>
</PropertyGroup>
<!-- Change the following so that this Task can find your vdproj file -->
<FileUpdate Files="$(MSBuildProjectDirectory)\..\Setup1\Setup1.vdproj"
Regex="(.SourcePath. = .8:).*\.config(.)"
ReplacementText="$1$(SetupProjectPath.Replace(`\`,`\\`))$2" />
<FileUpdate Files="$(MSBuildProjectDirectory)\..\Setup1\Setup1.vdproj"
Regex="(.TargetName. = .8:).*\.config(.)"
ReplacementText="$1$(TargetFileName).config$2" />
</Target>
5) The previous code must be changed, so that it can find your vdproj file. I have placed a comment in the code, indicating where you need to make the change.
Now, everytime you build your main project, the MSBuild will change the Setup project, so that it uses the correct app.config file. It may have drawbacks, but this solution can be polished and become better. If you need leave a comment, and I'll try to respond ASAP.
Resources I Used
MSBuild 4.0 is needed because I need to use String's Replace function, to replace single "\" to double "\" in the path. See
MSBuild Property Functions for details about using function in MSBuild.
I learned about the FileUpdate Task in this other question. The official project is MSBuild Community Tasks Project.
These two topics were important to my findings:
Trying to include configuration specific app.config files in a setup project
Problems with setup project - am I thick?
Another solution I've found is not to use the transformations but just have a separate config file, e.g. app.Release.config. Then add this line to your csproj file.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<AppConfig>App.Release.config</AppConfig>
</PropertyGroup>
This will force the deployment project to use the correct config file when packaging.
I combined the best of the following answers to get a fully working solution without using any external tools at all:
1. Setup App.Config transformations
Source: https://stackoverflow.com/a/5109530
In short:
Manually add additional .config files for each build configuration and edit the raw project file to include them similar to this:
<Content Include="App.config" />
<Content Include="App.Debug.config" >
<DependentUpon>App.config</DependentUpon>
</Content>
<Content Include="App.Release.config" >
<DependentUpon>App.config</DependentUpon>
</Content>
Then include the following XML at the end of the project file, just before the closing </project> tag:
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="AfterCompile" Condition="exists('app.$(Configuration).config')">
<TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" />
<ItemGroup>
<AppConfigWithTargetPath Remove="app.config" />
<AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
<TargetPath>$(TargetFileName).config</TargetPath>
</AppConfigWithTargetPath>
</ItemGroup>
</Target>
Finally edit the additional .config files to include the respective transformations for each build configuration:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!-- transformations here-->
</configuration>
2. Include the appropriate .config in the setup project
First, add a command in the postbuild event of your main project to move the appropriate transformed .config file to a neutral location (e.g. the main bin\ directory):
copy /y "$(TargetDir)$(TargetFileName).config" "$(ProjectDir)bin\$(TargetFileName).config"
(Source: https://stackoverflow.com/a/26521986)
Open the setup project and click the "Primary output..." node to display the properties window. There, add an ExludeFilter "*.config" to exclude the default (untransformed) .config file.
(Source: https://stackoverflow.com/a/6908477)
Finally add the transformed .config file (from the postbuild event) to the setup project (Add > File).
Done.
You can now freely add build configurations and corresponding config transforms and your setup project will always include the appropriate .config for the active configuration.
I accomplished this in a different manner with no external tools:
I added a post-build event that copied the target files to a 'neutral' directory (the root of the /bin folder in the project) and then added this file to the .vdproj. The deployment project now picks up whatever the latest built version is:
Post Build Command:
copy /y "$(TargetDir)$(TargetFileName).config" "$(ProjectDir)bin\$(TargetFileName).config"
This worked for what I needed without any external tools, and works nicely with SlowCheetah transformations.
Based off Alec's answer, here is a similar element that you can use along with the transformations and still get their full benefit:
<ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Content Include="$(OutputPath)$(AssemblyName).dll.config">
<InProject>false</InProject>
<Link>$(AssemblyName).dll.config</Link>
</Content>
</ItemGroup>
This way, you can use the SlowCheetah transforms or the built-in ones to transform your .config file, and then go into your Visual Studio Deployment Project (or other) and include the Content from the affected project in your Add -> Project Output... page easily, with minimal changes.
None of the above solutions or any articles worked for me in deployment/setup project. Spent many days to figure out the right solution. Finally this approach worked for me.
Pre requisites
I've used utility called cct.exe to transform file explicitly. You can download from here
http://ctt.codeplex.com/
I've used custom installer in setup project to capture installation events.
Follow these steps to achieve app config transformation
1) Add your desired config files to your project and modify your .csproj file like these
<Content Include="app.uat.config">
<DependentUpon>app.config</DependentUpon>
</Content>
<Content Include="app.training.config">
<DependentUpon>app.config</DependentUpon>
</Content>
<Content Include="app.live.config">
<DependentUpon>app.config</DependentUpon>
</Content>
I've added them as content so that they can be copied to output directory.
2) Add cct.exe to your project which you downloaded.
3) Add custom installer to your project which should look like this
[RunInstaller(true)]
public partial class CustomInstaller : System.Configuration.Install.Installer
{
string currentLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string[] transformationfiles = Directory.GetFiles(Path.GetDirectoryNam(Assembly.GetExecutingAssembly().Location), "app.*.config");
public CustomInstaller()
{
InitializeComponent();
// Attach the 'Committed' event.
this.Committed += new InstallEventHandler(MyInstaller_Committed);
this.AfterInstall += new InstallEventHandler(CustomInstaller_AfterInstall);
}
void CustomInstaller_AfterInstall(object sender, InstallEventArgs e)
{
try
{
Directory.SetCurrentDirectory(currentLocation);
var environment = Context.Parameters["Environment"];
var currentconfig = transformationfiles.Where(x => x.Contains(environment)).First();
if (currentconfig != null)
{
FileInfo finfo = new FileInfo(currentconfig);
if (finfo != null)
{
var commands = string.Format(#"/C ctt.exe s:yourexename.exe.config t:{0} d:yourexename.exe.config ", finfo.Name);
using (System.Diagnostics.Process execute = new System.Diagnostics.Process())
{
execute.StartInfo.FileName = "cmd.exe";
execute.StartInfo.RedirectStandardError = true;
execute.StartInfo.RedirectStandardInput = true;
execute.StartInfo.RedirectStandardOutput = true;
execute.StartInfo.UseShellExecute = false;
execute.StartInfo.CreateNoWindow = true;
execute.StartInfo.Arguments = commands;
execute.Start();
}
}
}
}
catch
{
// Do nothing...
}
}
// Event handler for 'Committed' event.
private void MyInstaller_Committed(object sender, InstallEventArgs e)
{
XmlDocument doc = new XmlDocument();
var execonfigPath = currentLocation + #"\yourexe.exe.config";
var file = File.OpenText(execonfigPath);
var xml = file.ReadToEnd();
file.Close();
doc.LoadXml(FormatXmlString(xml));
doc.Save(execonfigPath);
foreach (var filename in transformationfiles)
File.Delete(filename);
}
private static string FormatXmlString(string xmlString)
{
System.Xml.Linq.XElement element = System.Xml.Linq.XElement.Parse(xmlString);
return element.ToString();
}
}
Here I am using two event handlers CustomInstaller_AfterInstall in which I am loading correct config file and transforming .
In MyInstaller_Committed I am deleting transformation files which we don't need on client machine once we apply has been applied. I am also indenting transformed file because cct simply transforms elements were aligned ugly.
4) Open your setup project and add project output content file so that setup can copy config files like app.uat.config,app.live.config etc into client machine.
In previous step this snippet will load all available config files but we need supply right transform file
string[] transformationfiles = Directory.GetFiles(Path.GetDirectoryNam
(Assembly.GetExecutingAssembly().Location), "app.*.config");
For that I've added UI dialog on setup project to get the current config. The dialog gives options for user to select environment like "Live" "UAT" "Test" etc .
Now pass the selected environment to your custom installer and filter them.
It will become lengthy article if I explain on how to add dialog,how to set up params etc so please google them. But idea is to transform user selected environment.
The advantage of this approach is you can use same setup file for any environment.
Here is the summary:
Add config files
Add cct exe file
Add custom installer
Apply transformation on exe.config under after install event
Delete transformation files from client's machine
Modify setup project in such a way that
set up should copy all config files(project output content) and cct.exe into output directory
configure UI dialog with radio buttons (Test,Live,UAT..)
pass the selected value to custom installer
Solution might look lengthy but have no choice because MSI always copy app.config and doesn't care about project build events and transformations. slowcheetah works only with clickonce not setup project
The question is old, but the following could still help many folks out there.
I would simply use Wix WiFile.exe to replace the concerned file in the msi this way (for the sake of this example, we call your msi yourPackage.msi):
Step 1. From command prompt run: WiFile.exe "yourPackage.msi" /x "app.exe.config."
The above will extract the "wrong" app.exe.config file from the msi and place it the same directory as your msi;
Step 2. Place the new (prod) config file (must have the same name as the extracted file: app.exe.config) in same location as your msi;
This means that you are overwritting the app.exe.config that has just been extracted in step 1 above, with your new (production config file);
Step 3. From command prompt run: WiFile.exe "yourPackage.msi" /u "app.exe.config."
THAT'S ALL!
The above can be done in a few seconds. You could automate the task if you wanted, for instance, by running it as batch or else.
After running step 3 above, your msi will contain the new config file, which will now be installed at your clients' when they run the setup.

Resources