I have a post-checkout hook that substitutes the new branch name into some skeleton files in the "main" branch of the repository. This seems to cause pre-commit to indicate failure when it does what I intend, though this is normally correct behavior. Is there an option I'm missing? Can I tell pre-commit that any file modification by this hook is acceptable?
I see "The hook must exit nonzero on failure or modify files" in the documentation, and my hook does exit with an exit code of 0.
Related
I recently started implementing automatic tests for my code, and I noticed that the CI does not catch the warnings of the compiler - the tests are shown as successful even when there are warnings.
I have initially added a flag for the compiler to turn the warnings into errors and allow_failure=True, but the problem is that the compiler stops in the first warning->error and does not go through the entire compilation.
I then used the trick explained here to write the warnings into a file, and then test if the file is not zero:
- make 2> >(tee make.warnings)
- test ! -s make.warnings
After the whole compilation is done, this will give an error if there are warnings written to the file - and using allow_failure=True, this works for the cases where I have no errors/warnings, but also when I have warnings. However, if I have real errors, this will also be shown as a warning in CI, and will not stop the pipeline because of the allow_failure=True.
I could not find a way to allow_failure=True depending on something run in the script (without creating a new stage) or using some condition (i.e., if the file is empty or not). Is there a simple way to do this that I'm missing?
Since there is no condition per se, check out GitLab 13.8 (January 2021):
Control job status using exit codes
You can use the allow_failure keyword to prevent failed jobs from causing an entire pipeline to fail.
Previously, allow_failure only accepted boolean values of true or false but we’ve made improvements in this release.
Now you can use the allow_failure keyword to look for specific script exit codes.
This gives you more flexibility and control over your pipelines, preventing failures based on the exit codes.
See Documentation and Issue.
If you can use as condition an exit status of a script, that would be enough for allow_failure to be more specific.
So, I have a simple project with one Program (user-writen code) and then one Add-Inn (custom task) (it is very useful System Command executor add-inn, about you can read here)
So, when I get some condition in Program step, I want to stop my Project. I could stop Program, for example, using
ENDSAS
or
Abort abend
but, even if Program immediately stops (with error message in log), Add-Inn is execute! How disable executing of Add-Inn on condition (on error or any other)?
Thanks
P.S. Project will be execute in batch mode
If you're using an EG process flow, as you presumably are, then you need to set up a condition to run the add-in task.
Right click on your one program, select 'condition', add. Let's say you have a macro variable that is set to 0 if you have no problems or (some value) if you have a problem. (Could also use any of the automatic SYSERR type macro variables.)
Then, put your add-in task under "Then, run this task". You can add an Else or Else If if you want, or just leave that as None.
Then, EG won't run your task unless the macro variable is successful.
I'm having a hard time understanding how to properly install and uninstall custom actions, and what the purpose of rollback is. I have a custom action called CreateFSRegistryLink that creates a REG_LINK registry entry (which cannot be created by MSI/InstallShield directly AFAIK). I think I have this running properly for the most part because if the link is already there, it just returns ERROR_FUNCTION_NOT_CALLED, which MSI seems to handle gracefully, proceeding with the rest of the install. This ensures that multiple instances of the product can be installed cleanly (we have a multi-instance product).
The problem comes during un-install. CreateFSRegistryLink appears to be running again in non-rollback mode. From the MSI log I can see that it's running as it should during an install and but it also runs during an uninstall:
I'm checking the mode with:
if (!MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK))
When the condition is true I log a message, "CreateFSRegistryLink is running in non-rollback mode." When it is false, I log a message, "CreateFSRegistryLink is running in rollback mode, so was skipped." I have never seen the second message show up in the log.
I have CreateFSRegistryLink set up with In-Script execution of "Deferred Execution in System Context." I also have another custom action DeleteFSRegistryLink set up with In-Script execution of "Rollback Execution in System Context". I see it getting skipped during an install, but not during an un-install (I suspect it's running normally during an un-install, but have not added logging to confirm this).
I also have a custom action CountOtherFSSystems that sets FS_SystemCount to the number of systems (instances) besides the current instance. I set DeleteFSRegisryLink to have a condition to only run when FS_SystemCount<1 in the Exec sequence. This is how I can tell that it is being skipped during an install because MSI reports that the condition wasn't met and so DeleteFSRegistryLink was skipped. I expect this to help ensure that it only runs when the last instance is being un-installed. I think this condition is working based on log output, but I don't know how to get this DeleteFSRegistryLink custom action to run properly during un-install without the CreateFSRegistryLink action re-installing the link. The last reference to DeleteFSRegistryLink I see in the log is:
MSI (s) (08:CC) [09:42:23:708]: Executing op: CustomActionSchedule(Action=DeleteFSRegistryLink,ActionType=3329,Source=BinaryData,Target=DeleteFSRegistryLink,)
I haven't added logging to this function yet, so I don't know if it ran, but when the un-install is done, the link in the registry is still there. This is not entirely surprising because immediately after that I see that CreateFSRegistryLink ran again:
MSI (s) (08:CC) [09:42:23:708]: Executing op: ActionStart(Name=CreateFSRegistryLink,,)
Action 9:42:23: CreateFSRegistryLink.
MSI (s) (08:CC) [09:42:23:708]: Executing op: CustomActionSchedule(Action=CreateFSRegistryLink,ActionType=3073,Source=BinaryData,Target=CreateFSRegistryLink,)
MSI (s) (08:0C) [09:42:23:739]: Invoking remote custom action. DLL: C:\windows\Installer\MSI37E1.tmp, Entrypoint: CreateFSRegistryLink
MSI (s) (08:70) [09:42:23:739]: Generating random cookie.
MSI (s) (08:70) [09:42:23:739]: Created Custom Action Server with PID 7640 (0x1DD8).
MSI (s) (08:18) [09:42:23:786]: Running as a service.
MSI (s) (08:18) [09:42:23:786]: Hello, I'm your 32bit Elevated custom action server.
CreateFSRegistryLink is running in non-rollback mode.
I followed the rule at https://msdn.microsoft.com/en-us/library/aa371369(v=vs.85).aspx of "A rollback custom action must always precede the deferred custom action it rolls back in the action sequence" which is still really not making sense to me seeing this log output and results. I think I'm missing a few key points here.
This is on my 'required reading' list for MSI and a good place to start:
Installation Phases and In-Script Execution Options for Custom Actions in Windows Installer
The idea is that every change made by MSI should be transactional. You should be able to rollback the state change on failure during an install, upgrade, repair or uninstall.
Occasionally you'll come across an API where this is not possible. An example would be deleting a user account or interacting with the old IIS metabase API. If the API doesn't support a .commit() .rollback() ability then you have to just make the change in the commit phase execution. Considering that commit phase can be disabled by disabling rollback you have to do it early in those scenarios.
Read the white paper a few times, digest it a bit and then follow up with any other questions that you still have.
Edit: This is how I ended up setting up my custom actions:
CountOtherFSSystems runs with Immediate Execution after InstallInitialize under all circumstances to set FS_SystemCount to the number of other instances that are installed.
RollbackFSRegistryLink runs with Rollback Execution in System Context after CountOtherFSSystems under the condition FS_SystemCount<1 And $FSRegistry = 3 (When the FSRegistry component was being installed local). It calls the function to delete the registry link.
CreateFSRegistryLink runs with Deferred Execution in System Context after RollbackFSRegistryLink under the condition $FSRegistry=3. It calls the function to create the registry link.
A bunch of other functions in the sequence execute, and then we get to the standard action WriteRegistryValues.
RollbackDeleteFSRegistryLink runs with Rollback Execution in System Context after WriteRegistryValues under the condition $FSRegistry<>3 (when the FSRegistry component was being removed, but the rollback needs to put it back). It calls the function to create the registry link.
DeleteFSRegistryLink runs with Deferred Execution in System Context after RollbackDeleteFSRegistryLink under the condition FS_SystemCount<1 AND $FSRegistry <> 3. It calls the function to delete the registry link.
TestError runs with Deferred Execution in System Context after DeleteFSRegistryLink. It calls a test function that just returns an error condition if the user says it's OK (via MSIProcessMessage) to introduce an error for test purposes here. (This function will be disabled for the production builds.)
I tested the following cases:
Error during installation of first instance - no registry entries or links are created.
Error during installation of second instance - only the first instance's registry entries remain, and the link remains also.
Error during uninstall of second instance - both instances and the link remain in the registry.
Error during un-install of last remaining instance - While the error is still displayed (before rollback occurs) I can see that the registry entries and link are all gone, and after proceeding, I see the rollback has restored the registry entries and the link.
Successful un-install of second instance - link and first instance's registry entries remain.
Successful un-install of last remaining instance - link and all registry entries are removed.
Please comment if you see anything I missed here. It seems pretty comprehensive to me.
To throw in my 2 cents: The issue seems to be related to custom action conditions. Regarding your call to MsiGetMode to see if it's a rollback, why bother? You sequence a rollback custom action before your actual deferred CA, and by definition it will be called only if the original custom action was called, and it's defined as a rollback CA and it needs no conditions. It may be that your uninstall CA can be the same as the rollback CA, but strictly speaking an uninstall CA can assume that its counterpart install CA worked correctly if it is coded correctly and failure causes the install to fail, whereas a rollback CA may need to assume that the install CA may have only partially worked and needs to check more system state.
If CreateRegistryFSLink is being called on uninstall then your condfition on that CA is incorrect.
If your code did or did not do something then it's up to you to remember what it did and the rollback CA undoes it.
The rest of it appears to be about the conditions on your custom actions. If you want one to be called only on uninstall of the product, then use REMOVE="ALL". If you have CAs related specifically to feature or component uninstall then (as Chris says) use a component or feature condition, they are here:
https://msdn.microsoft.com/en-us/library/aa368012(v=vs.85).aspx
If you want an uninstall CA to run as long as the product is not being upgraded, then REMOVE="ALL" and NOT UPGRADINGPRODUCTCODE will work.
So if you're still stuck, it may help to post your definitions of the CAs, in particular the conditions and types.
In developing Selenium extensions I have scripting to verify the correct handling of failure cases. Unfortunately, I have to execute those commands one-by-one in the IDE, and manually examine each error message. What I would like to do is define a custom Selenium command that I can insert before each command that intentionally fails in a given way. Eg: willFail|expected-error-text.
In other words, I want to alter Selenium command completion behavior such that if the next command throws the given error message, then the result is success and the script continues. But if it succeeds or throws a different error, then the script stops with an error.
I imagine this will involve setting observer function(s), and/or intercepting Selenium function(s). I'd expect the issues to be:
How/where to do the initialization. The relevant Selenium objects can be hard to find.
What/when to return in order to alter the result.
Is there something else left out-of-sync by altering a result?
The PowerDebugger extension allows you to pause the IDE upon a failure, and then resume. So I suspect that the how-to is in there somewhere. But I can't quite figure out how it hooks into Selenium command processing. Samit Badle, are you out there?
I am using Selenium IDE 2.2.0.
With some experimentation I have found that the function TestLoop.resume() is responsible for determining the outcome of each command.
It is defined in chrome/content/selenium-core/scripts/selenium-executionloop.js.
This function executes the command, and either halts the script, or allows it to continue.
To alter this behavior, a Selenium extension can temporarily replace this function with a custom version. To accomplish this, save a reference of editor.selDebugger.runner.IDETestLoop.prototype.resume, and replace it with the custom function. The custom function should then restore the native function, and carry out command execution as appropriate.
I have some logging in my application (it happens to be log4cxx but I am flexible on that), and I have some unit tests using the boost unit test framework. When my unit tests run, I get lots of log output, from both the passing and failing tests (not just boost assertions logged, but my own application code's debug logging too). I would like to get the unit test framework to throw away logs during tests that pass, and output logs from tests that fail (I grew to appreciate this behaviour while using python/nose).
Is there some standard way of doing this with the boost unit test framework? If not, are there some start of test/end of test hooks that I could use to buffer my logs and conditionally output them to implement this behaviour myself?
There are start of test and end of test hooks that you can use for this purpose. To set up these hooks you need to define a subclass of boost::unit_test::test_observer, create an instance of the class that will persist throughout the entire test (either a static global object or a BOOST_TEST_GLOBAL_FIXTURE), and then pass the class to boost::unit_test::framework::register_observer.
The method to override with a start of test hook is test_unit_start, and the method to override with an end of test hook is test_unit_finish. However, these hooks fire both for test suites as well as individual test cases, which may be an issue depending on how the hooks are set up. The test_unit_finish hook also doesn't explicitly tell you whether a given test actually passed, and there doesn't seem to be one clear and obvious way to get that information. There is a boost::unit_test::results_collector singleton, which has a results() method, and if you pass it the test_unit_id of the test unit provided to test_unit_finish, you get a test_results object that has a passed() method. I can't really see a way to get the test_unit_id that is clearly part of the public API -- you can just directly access the p_id member, but that could always change in a future boost version. You could also manually track whether each test is passing or failing using the assertion_result, exception_caught, test_unit_aborted, and test_unit_timed_out hooks from the test_observer subclass (assertion_result indicates a failure of the current test whenever its argument is false and every other hook indicates a failure if it is called at all).
According to the Boost.Test documentation, run your test executable with --log_level=error. This will catch only failing test cases.
I checked that it works using a BOOST_CHECK(false) on an otherwise correctly running project with a few thousand unit tests.
Running with --log_level=all gives the result of all assertions. I checked that by piping it to wc -l that the number of lines in the log is exactly the same as the number of assertions in the tests (which number is also reported by --report_level=detailed). You could of course also grep the log for the strings error or failed.