<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Testing on despatches</title><link>https://icle.es/tags/testing/</link><description>Recent content in Testing on despatches</description><generator>Hugo</generator><language>en</language><lastBuildDate>Fri, 20 Jun 2025 09:25:00 +0100</lastBuildDate><atom:link href="https://icle.es/tags/testing/index.xml" rel="self" type="application/rss+xml"/><item><title>How to run your lambda code locally as its role (for testing)</title><link>https://icle.es/2023/11/14/automated-testing-of-aws-lambda-locally/</link><pubDate>Tue, 14 Nov 2023 14:23:37 +0000</pubDate><guid>https://icle.es/2023/11/14/automated-testing-of-aws-lambda-locally/</guid><description>&lt;p>While AWS Lambda is fantastic in providing a serverless platform with few
worries about maintaining servers, it is not the easiest to test in an automated
fashion with rapid feedback.&lt;/p>
&lt;p>You could write end to end tests, but it means a deployment after each change
and then checking the logs to see what failed. Even if you use iac
(terraform/pulumi), the deployment will take seconds or a minute or two - not
exact rapid test feedback.&lt;/p>
&lt;p>What I have been doing is to set up a hook which is called from the lambda
handler, which can also be called locally. Within the test, I then assume the
role that runs the lambda and then test the hook.&lt;/p>
&lt;p>This mechanism allows to me easily test that the permissions are set up
correctly and that details are in place for the code to work.&lt;/p>
&lt;p>For the full end to end test, I then have a simple smoke test or two.&lt;/p>
&lt;p>The code samples are in golang(only because it happens to be my current language
of choice), but the idea should be equally applicable in other languages.&lt;/p></description><content:encoded><![CDATA[<p>While AWS Lambda is fantastic in providing a serverless platform with few
worries about maintaining servers, it is not the easiest to test in an automated
fashion with rapid feedback.</p>
<p>You could write end to end tests, but it means a deployment after each change
and then checking the logs to see what failed. Even if you use iac
(terraform/pulumi), the deployment will take seconds or a minute or two - not
exact rapid test feedback.</p>
<p>What I have been doing is to set up a hook which is called from the lambda
handler, which can also be called locally. Within the test, I then assume the
role that runs the lambda and then test the hook.</p>
<p>This mechanism allows to me easily test that the permissions are set up
correctly and that details are in place for the code to work.</p>
<p>For the full end to end test, I then have a simple smoke test or two.</p>
<p>The code samples are in golang(only because it happens to be my current language
of choice), but the idea should be equally applicable in other languages.</p>
<h1 id="assuming-the-role">Assuming The Role</h1>
```go
  roleToAssume := os.Getenv("AUTH_LAMBDA_ROLE_ARN")

    ctx := context.TODO()
    cfg, err := config.LoadDefaultConfig(ctx)

    if err != nil {
        logger.Fatal("error: ", err)
    }
    // Create the credentials from AssumeRoleProvider to assume the role
    // referenced by the "myRoleARN" ARN using the MFA token code provided.
    creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), roleToAssume)

    logger.Debugf("creds: %v", creds)

    cfg.Credentials = aws.NewCredentialsCache(creds)
```
<p>the cfg is then passed into the <code>New</code> method for the resource you are interested
in. e.g.:</p>
```go
   ssmClient := ssm.NewFromConfig(cfg)
```
<h1 id="working-example">Working Example</h1>
<p>You can find a full, working example test in
<a href="https://github.com/drone-ah/wordsonsand">my github repo</a> under
<a href="https://github.com/drone-ah/wordsonsand/tree/main/post/2023/11/autolambdatest">post/2023/11/autolambdatest</a></p>
<p>NOTE: It WILL automatically try and deploy a role and a ssm parameter, and it
will delete it after the test.</p>
<p>The <code>BeforeSuite</code> will deploy the minimum configuration to be able to run the
test, and the <code>AfterSuite</code> will destroy the same stack.</p>
<p>You will likely need to log into pulumi to get this test to work.</p>
<p>If you run into permissions issue for AssumeRole, read on.</p>
<h1 id="assumerole-permissions">AssumeRole Permissions</h1>
<p>For this to work, the user running the tests need to have permissions to
<code>AssumeRole</code>.</p>
<p>There are two steps to this. The first part is to allow &quot;anyone&quot; to
<code>AssumeRole</code> the relevant role:</p>
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<your-account-id>:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
<p>This will allow &quot;any user&quot; to assume the role, as long as they have the
permission to do so.</p>
<p><code>arn:aws:iam::[your-account]:root</code> is a special user the represents the account
(and the non-IAM root user). Since IAM (user, roles etc.) exists under the
&quot;root&quot; account, all calls are also authenticated by this account - i.e. all
users, roles etc. in IAM is also this account. There is
<a href="https://www.reddit.com/r/aws/comments/oorjl2/what_exactly_is_the_root_iam_principal/">a post on reddit discussing what exactly the root iam principal is for more information</a></p>
<p>Finally, unless you have the <code>Administrator</code>Access policy set against your
account, you will also need to attach a policy to the relevant group (or your
user) that grants permissions to call <code>sts:AssumeRole</code> (or <code>*</code>)</p>
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "123",
      "Effect": "Allow",
      "Action": ["sts:AssumeRole"],
      "Resource": ["arn:aws:iam::123456789012:role/desired-role"]
    }
  ]
}
```
<p>You can of course, also use <code>*</code> for Resource above to allow the user/group to
Assume Any role. In practice, you might want to automate this as part of the
creation of the relevant roles. (i.e. create the role, then give the relevant
group permissions to Assume that role).</p>]]></content:encoded></item><item><title>Unable to write to $HOME/.pulumi/credentials.json during bazel test</title><link>https://icle.es/2023/11/14/unable-to-write-to-home-pulumi-credentials-json-during-bazel-test/</link><pubDate>Tue, 14 Nov 2023 13:46:46 +0000</pubDate><guid>https://icle.es/2023/11/14/unable-to-write-to-home-pulumi-credentials-json-during-bazel-test/</guid><description>&lt;h1 id="the-problem">The Problem&lt;/h1>
&lt;p>You can add it to your ~/.bazelrc (it needs the path to be absolute)&lt;/p>
&lt;p>From our integration tests, we run &lt;code>pulumi stack output&lt;/code> (or in some cases
&lt;code>pulumi up&lt;/code>) through the automation API before we run the tests so that we can&lt;/p>
&lt;ul>
&lt;li>Confirm that the stack is up&lt;/li>
&lt;li>Get the relevant parameters (actual names of lambdas / dynamo db tables etc.)&lt;/li>
&lt;/ul>
&lt;p>However, since we use bazel for our tests, we ran into a small problem in that
Bazel (rightly) prevents the tests from writing to anything outside the sandbox.
This restrictions results in this error&lt;/p>
```
error: open /home/&lt;username>/.pulumi/credentials.json: read-only file system
```</description><content:encoded><![CDATA[<h1 id="the-problem">The Problem</h1>
<p>You can add it to your ~/.bazelrc (it needs the path to be absolute)</p>
<p>From our integration tests, we run <code>pulumi stack output</code> (or in some cases
<code>pulumi up</code>) through the automation API before we run the tests so that we can</p>
<ul>
<li>Confirm that the stack is up</li>
<li>Get the relevant parameters (actual names of lambdas / dynamo db tables etc.)</li>
</ul>
<p>However, since we use bazel for our tests, we ran into a small problem in that
Bazel (rightly) prevents the tests from writing to anything outside the sandbox.
This restrictions results in this error</p>
```
error: open /home/<username>/.pulumi/credentials.json: read-only file system
```
<h1 id="the-solution">The Solution</h1>
<p>The easiest way to solve this is to ask <code>bazel</code> to allow writing to this
location, which you can do with:</p>
```bash
bazel test ... --sandbox_writable_path=$HOME/.pulumi
```
<p><code>bazel</code> needs to the path to be absolute, so <code>~/.pulumi</code> won't work.</p>
<h1 id="automation">Automation</h1>
<p>It is annoying to add this flag into all the tests, but there is an way to
automatically add it to all tests. You can add it to <code>.bazelrc</code>. Due to the
aforementioned requirement for the path to be absolute, it is not possible to
put it into the git repo root. However, you can put it into your home directory
rool <code>.bazelrc</code></p>
<p><code>$HOME/.bazelrc</code></p>
```
test --sandbox_writable_path=/home/<your-username>/.pulumi
```]]></content:encoded></item><item><title>Separating out integration tests for golang in Bazel</title><link>https://icle.es/2023/11/13/separating-out-integration-tests-for-golang-in-bazel/</link><pubDate>Mon, 13 Nov 2023 13:47:53 +0000</pubDate><guid>https://icle.es/2023/11/13/separating-out-integration-tests-for-golang-in-bazel/</guid><description>&lt;p>There are many kinds of automated tests and two main kinds are integration tests
and unit tests.&lt;/p>
&lt;p>Unit tests are designed to run as fast as possible, so any slower processes like
databases are mocked out. While super helpful and powerful in terms of providing
confidence in the software, it should be only one part of the testing strategy.&lt;/p>
&lt;p>Integration tests, as is implied runs tests of the different part of the
software integrated together. Technically speaking, you can still mock out the
database and other slower layers to keep it running quickly. However, there is
value in including a database or other slower services in the process to test as
them in an automated fashion.&lt;/p>
&lt;p>What this does mean though, is that you want to be able to run only the unit
tests or run the integration tests as well. You might also want to have smoke
tests, which are run on your live production environment.&lt;/p></description><content:encoded><![CDATA[<p>There are many kinds of automated tests and two main kinds are integration tests
and unit tests.</p>
<p>Unit tests are designed to run as fast as possible, so any slower processes like
databases are mocked out. While super helpful and powerful in terms of providing
confidence in the software, it should be only one part of the testing strategy.</p>
<p>Integration tests, as is implied runs tests of the different part of the
software integrated together. Technically speaking, you can still mock out the
database and other slower layers to keep it running quickly. However, there is
value in including a database or other slower services in the process to test as
them in an automated fashion.</p>
<p>What this does mean though, is that you want to be able to run only the unit
tests or run the integration tests as well. You might also want to have smoke
tests, which are run on your live production environment.</p>
<h1 id="how">How</h1>
<p>You could define a separate target in your <code>BUILD</code> file with the unit tests and
let <code>gazelle</code> automatically build your default test target with all the tests. I
found this frustrating to use as I had to keep tweaking the dependencies
manually whenever anything changed (which happened often)</p>
<h2 id="tagging">Tagging</h2>
<p>The easiest way to achieve this for golang and bazel is to tag your source code
files. You can do this by adding the following to the top of your integration
test files</p>
<p><code>something_integration_test.go</code></p>
```go
//go:build integration_test

package somepackage
```
<p>You can pick any tag name you want instead of <code>integration_test</code> like
<code>integration</code>, <code>smoke_test</code> etc.</p>
<h2 id="ide-support">IDE Support</h2>
<p>You will likely need to add this source file into the IDEs build constraints to
get the IDE to treat it as a source file. In IntelliJ (IDEA/Goland), you will be
warned of this</p>
<p>
  <img src="/assets/2023/11/image.png" alt="idea screenshot, main_test.go is ignored by build tool">

</p>
<p>If you click <code>Edit settings</code>, you can add the tag in</p>
<p>
  <img src="/assets/2023/11/image-1.png" alt="set custom tags in build tags">

</p>
<p>When running <code>gazelle</code>, you want to include the files with these tags</p>
<h2 id="gazelle">Gazelle</h2>
```bash
bazel run //:gazelle -- -build_tags=integration_test
```
<p>If you have multiple tags, you can separate them with commas. This command will
generate a test target with all of the source files and its dependencies</p>
<h2 id="bazel-integration-on-test">Bazel Integration on test</h2>
<p>To run only the unit tests, you test as normal:</p>
```bash
bazel test ... # or the specific target, and it'll run only the unit tests
```
<p>To run the integration tests as well, include that tag</p>
```bash
bazel test ... --define  gotags=integration_test # Will run unit & integration tests
```
<h2 id="run-only-unit-tests">Run only Unit Tests</h2>
<p>This setup will currently not allow you to run ONLY the integration tests. To be
able to do that you'll need to add a <code>unit_test</code> tag to the unit test files so
that you can exclude them.</p>
```
something_test.go
```
```go
//go:build integration_test

package somepackage
```
<p>You can then run only the unit tests with</p>
```bash
bazel test … --define gotags=unit_test # Will run unit & integration tests
```
<p>Only the integration tests</p>
```bash
bazel test … --define gotags=integration_test # Will run unit & integration tests
```
<p>Or both:</p>
```bash
bazel test … --define gotags=unit_test,integration_test # Will run unit & integration tests
```
<h2 id="simpler-gazelle-command">Simpler gazelle command</h2>
<p>You can enable the tags by default in the <code>BUILD</code> file so that you don't have
to pass the tags into gazelle each time.</p>
<p><code>BUILD</code></p>
```starlark
# gazelle:build_tags unit_test,integration_test
```
<p>You can then just run <code>bazel run //:gazelle</code> which will run with these tags
enabled.</p>
<h1 id="sample-source">Sample Source</h1>
<p>You can find sample source code demonstrating this in
<a href="https://github.com/drone-ah/wordsonsand">my github repo</a>, under
<a href="https://github.com/drone-ah/wordsonsand/tree/main/post/2023/11/separatetests">post/2023/11/separatetests</a></p>]]></content:encoded></item><item><title>Hibernate Domain Model Testing</title><link>https://icle.es/2008/12/23/hibernate-domain-model-testing/</link><pubDate>Tue, 23 Dec 2008 22:14:42 +0000</pubDate><guid>https://icle.es/2008/12/23/hibernate-domain-model-testing/</guid><description>&lt;p>One of my pet peeves with Hibernate has always been how difficult it was to test
it. I want to test the persistence of data, loading the data back and any
specific funtionality with the domain model.&lt;/p>
&lt;p>Simple? NO! The main problem was the management of the data set. I had set up,
in the past fairly interesting classes to test the functionality using
reflection, and injecting the data from the classes themselves through the data
provider mechanism of &lt;a href="http://testng.org/d" title="TestNG">TestNG&lt;/a>. However, this was
error prone and clunky at best. It also made dependency management of data quite
cumbersome.&lt;/p>
&lt;p>With a view to resolving this, I also looked at
&lt;a href="http://dbunit.sourceforge.net/" title="DbUnit">DbUnit&lt;/a>,
&lt;a href="http://unitils.org/" title="Unitils">unitils&lt;/a> and
&lt;a href="http://ejb3unit.sourceforge.net/" title="Ejb3Unit">Ejb3Unit&lt;/a>. They all did some
things that I liked but lacked some functionality that was important.&lt;/p></description><content:encoded><![CDATA[<p>One of my pet peeves with Hibernate has always been how difficult it was to test
it. I want to test the persistence of data, loading the data back and any
specific funtionality with the domain model.</p>
<p>Simple? NO! The main problem was the management of the data set. I had set up,
in the past fairly interesting classes to test the functionality using
reflection, and injecting the data from the classes themselves through the data
provider mechanism of <a href="http://testng.org/d" title="TestNG">TestNG</a>. However, this was
error prone and clunky at best. It also made dependency management of data quite
cumbersome.</p>
<p>With a view to resolving this, I also looked at
<a href="http://dbunit.sourceforge.net/" title="DbUnit">DbUnit</a>,
<a href="http://unitils.org/" title="Unitils">unitils</a> and
<a href="http://ejb3unit.sourceforge.net/" title="Ejb3Unit">Ejb3Unit</a>. They all did some
things that I liked but lacked some functionality that was important.</p>
<p>This led me to write a simple testing infrastructure. The goal was
straightforward.</p>
<ul>
<li>I need to be able to define data in a CSV (actually it was seperated by the
pipe character |, so PSV) based on entities.</li>
<li>The framework should automatically persist the data (and fail on errors)</li>
<li>It should test that it can load all that data back</li>
<li>It should run as many automated tests on the DOM as possible.</li>
</ul>
<p>The framework uses the CSV files to read the data for each of the classes (using
the excellent <a href="http://supercsv.sourceforge.net/" title="SuperCsv">SuperCsv</a> library).
It needs an Id field for internal reference. As long as the id&rsquo;s match within
the CSV files for the relationships, it will be persisted correctly into the
database even when the persisted id&rsquo;s are different.</p>
<p>For example, I could have a Contact.csv with 5 records (ids 1 through 5) and a
Company.csv with 3 records (ids 1 through 3).</p>
<p>The Contact.csv records can map to the id specified in the Company.csv file and
when the records get persisted, they will be associated correctly, even if the
id&rsquo;s in the database end up being different.</p>
<p>The framework also looks for the CSV file which has the same name as the class
within the location defined within the configuration file. This means that as
long as the filename matches the class name, the data loading is automatic.</p>
<p>For simple classes, the Test case is as simple as:</p>
```java
public class CompanyTest extends DOMTest<Company> {

public CompanyTest() { super(Company.class); } }
```
<p>The system (with the help of testNG) is also easily flexible to define object
model dependencies. Just override the persist method (which just calls the
super.persist) and define the groups to be persist and <code>&lt;object&gt;.persist</code></p>
<p>in this particular case, it would be</p>
```java
@override
@Test(groups={"persist", "Company.persist"}
public void persist() {
    super.persist();
}
```
<p>For all dependent classes, I then depend on the Company.persist group (For the
ContactTest class for example, since it needs to link to the Company object)</p>
<p>You can specify OneToOne and ManyToOne relationships with just the CSV files -
just defining the field name and the id of the object to pull in.</p>
<p>ManyToMany is more complex and requires an interim object to be created within
the test section. If the Contact to Company relationship above was ManyToMany,
we would create a ContactCompany class with just the two fields - Contact &amp;
Company, then create a csv file with three fields, id, Contact, &amp; Company. The
framework currently always needs an id field.</p>
<p>You would then need to write a method within the ContactTest or CompanyTest(I
use the owning side) to read the CSV file in and pump the data. This process is
a little bit complex just now.</p>
<p>With an appropriate amount of test data, you are able to write a test suite that
can consistently test your domain model. More importantly, you can configure it
to drop the database at the start of each run so that once the tests are
complete, you have a database structure and data than can be used for testing of
higher level components (EJB/Spring/UI/WebApp)</p>
<p>We currently use this framework to test the domain model as well as distribute a
data set for development and testing of the higher tier functionalities.</p>
<p>For the future, there are several additional features this framework needs:</p>
<ul>
<li>It currently needs the setters/getters &amp; constructors to be public. This needs
to be FIXED</li>
<li>Refactor the ManyToMany Relationship code to make it easier and simpler to
test and pump data</li>
<li>See if we can ensure that additional tests which data is done within a
transaction and rolled back so that the database is left in the &ldquo;CSV Imported&rdquo;
state on completion of tests</li>
<li>Easier Dependency management if possible</li>
</ul>
<p>This framework is still inside the walls of Kraya, but once the above issues are
resolved and it is in a releasable state, it will be published into the open
source community. If you are interested in getting a hold of it, email me and
I&rsquo;ll provide you with the latest version.</p>
<p>The easier and quicker it is to test, the more time we can spend on writing
code&hellip; :-) The higher the coverage of the tests, the more confident you can be
of your final product.</p>
<p>To more testing&hellip;</p>]]></content:encoded></item></channel></rss>