<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 17, 2016 at 9:49 PM, Martin Mucha <span dir="ltr">&lt;<a href="mailto:mmucha@redhat.com" target="_blank">mmucha@redhat.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Having such builders would simplify our lives for sure. But I&#39;d really try to avoid any autogeneration. I would cost lots of man hours to make it happen and result won&#39;t be good. If we agree to use this approach, and everyone write new methods as they&#39;re needed, &#39;some basic builders&#39; come to life very easy and fast.</blockquote><div><br></div><div>That&#39;s what I had in mind and I have pretty good experience with that pattern from previous projects. I am also against autogeneration for the mentioned reasons in that case. If you are on a greenfield project, Lombok has a nice @Builder [1] in general but it does also not fit very well here.<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> Also some places already has such similar builders — like org.ovirt.engine.core.bll.network.host.HostSetupNetworksValidatorTest.HostSetupNetworksValidatorBuilder.<br>
<span class=""><font color="#888888"><br>
M.<br>
</font></span><div class=""><div class="h5"><br>
----- Original Message -----<br>
&gt; Hi Roman,<br>
&gt;<br>
&gt; I really like the idea behind domain object builders.<br>
&gt;<br>
&gt; Maybe a silly question, but how much effort would it take<br>
&gt; to autogenerate some &quot;basic&quot; builders from domain objects?<br>
&gt; (without DAO/Integration test related stuff like prePersist<br>
&gt; override etc.)<br>
&gt;<br>
&gt; From the &quot;basic&quot; builders we could derive DAO/Integration<br>
&gt; ones as subclasses. This way, the domain object specific<br>
&gt; stuff wouldn&#39;t have to be kept in sync by hand, and we can<br>
&gt; subclass only if we need to make a builder DAO/Integration<br>
&gt; test aware.<br>
&gt;<br>
&gt; Vojtech<br>
&gt;<br>
&gt;<br>
&gt; ----- Original Message -----<br>
&gt; &gt; From: &quot;Roman Mohr&quot; &lt;<a href="mailto:rmohr@redhat.com">rmohr@redhat.com</a>&gt;<br>
&gt; &gt; To: &quot;Eyal Edri&quot; &lt;<a href="mailto:eedri@redhat.com">eedri@redhat.com</a>&gt;<br>
&gt; &gt; Cc: &quot;Juan Antonio Hernandez Fernandez&quot; &lt;<a href="mailto:jhernand@redhat.com">jhernand@redhat.com</a>&gt;, &quot;devel&quot;<br>
&gt; &gt; &lt;<a href="mailto:devel@ovirt.org">devel@ovirt.org</a>&gt;<br>
&gt; &gt; Sent: Thursday, April 14, 2016 1:05:25 PM<br>
&gt; &gt; Subject: Re: [ovirt-devel] Integration tests future (and very nice<br>
&gt; &gt; alternative for the DAO fixture file)<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; On Thu, Apr 14, 2016 at 12:32 PM, Eyal Edri &lt; <a href="mailto:eedri@redhat.com">eedri@redhat.com</a> &gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; Will that replace the current DAO tests running in CI?<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; For now no. What you can do with the builders reagarding to the DAO tests<br>
&gt; &gt; is<br>
&gt; &gt; creating test scenarios for the database. So instead of adding entities to<br>
&gt; &gt; the fixture file you can set up clean sceanrios for your tests just with<br>
&gt; &gt; the<br>
&gt; &gt; builders in @Test or @Before methods.<br>
&gt; &gt;<br>
&gt; &gt; Integration tests are using Arqullian with the spring transaction manager<br>
&gt; &gt; and<br>
&gt; &gt; will probably an extra CI job which passes the right maven flags.<br>
&gt; &gt; Arquillian<br>
&gt; &gt; is nice here because we are much closer to a real JBoss than with Spring.<br>
&gt; &gt;<br>
&gt; &gt; The reason why we do not use Arquillian and only the builders for the DAO<br>
&gt; &gt; test is that you would need a full JBoss downloaded in the background to<br>
&gt; &gt; give us a transaction manager which does the same thing as springs<br>
&gt; &gt; transaction manager does during the build.<br>
&gt; &gt;<br>
&gt; &gt; The JBoss people are currently working on modularizing all their JBoss<br>
&gt; &gt; libraries (for JBoss Swarm) and I hope that in the future we can drop the<br>
&gt; &gt; spring transaction manager and do everything with arquillian and the JBoss<br>
&gt; &gt; transaction manager.<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; On Wed, Apr 13, 2016 at 4:22 PM, Roman Mohr &lt; <a href="mailto:rmohr@redhat.com">rmohr@redhat.com</a> &gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; Hi all,<br>
&gt; &gt;<br>
&gt; &gt; In [1] you can find some patches which are meant to improve the test<br>
&gt; &gt; writing<br>
&gt; &gt; experience in ovirt-engine.<br>
&gt; &gt;<br>
&gt; &gt; They provide the following things:<br>
&gt; &gt;<br>
&gt; &gt; A) Domain Object builders which can be used for creating and/or persisting<br>
&gt; &gt; domain objects [2]<br>
&gt; &gt; B) DAO testing without writing fixtures because of the builders<br>
&gt; &gt; C) Integration testing for commands in conjunction with a real database<br>
&gt; &gt; Arquillian, injectable commands and the builders [3]<br>
&gt; &gt;<br>
&gt; &gt; # How to run what?<br>
&gt; &gt;<br>
&gt; &gt; A) In normal unit tests just create a new instance of a builder and use it.<br>
&gt; &gt; This should help us to get rid of all the small createDefaultVm(),<br>
&gt; &gt; createHostWithX() helper methods in our tests.<br>
&gt; &gt;<br>
&gt; &gt; B) In dao tests just inject them and go ahead. The advantage of not using<br>
&gt; &gt; the<br>
&gt; &gt; fixture file is that we can now set up clean scenarios for every test in a<br>
&gt; &gt; setup method. See example 2 below on how easy it is to set up a new<br>
&gt; &gt; cluster.<br>
&gt; &gt;<br>
&gt; &gt; C) Arquillian integration tests need to be marked with<br>
&gt; &gt; &quot;@Category(IntegrationTest.class)&quot; and can inherit from<br>
&gt; &gt; TransactionalTestBase. The @Category annotation makes sure that the<br>
&gt; &gt; integration tests are only run when<br>
&gt; &gt;<br>
&gt; &gt; mvn clean verify -DskipITs=false<br>
&gt; &gt;<br>
&gt; &gt; is invoked. Note that these tests are then executed in the integration test<br>
&gt; &gt; phase of maven. For them we use the maven-failsafe-plugin[5] which will<br>
&gt; &gt; also<br>
&gt; &gt; make sure that the testing database is up to date. See [4] for more<br>
&gt; &gt; details.<br>
&gt; &gt;<br>
&gt; &gt; # Examples<br>
&gt; &gt;<br>
&gt; &gt; 1) Add a running VM to a host, persist everything to the database and load<br>
&gt; &gt; all VMs which are running on the host:<br>
&gt; &gt;<br>
&gt; &gt; VDS host = vdsBuilder.cluster(persistedCluster).persist();<br>
&gt; &gt; vmBuilder.host(host).up().persist();<br>
&gt; &gt; List&lt;VM&gt; vms = vmDao.getAllRunningForVds(host.getId());<br>
&gt; &gt;<br>
&gt; &gt; 2) Add 10 hosts with 1 GB of RAM to a cluster, persist the hosts to the<br>
&gt; &gt; database in a DAO test:<br>
&gt; &gt;<br>
&gt; &gt; public class MyHostDaoTest extends BaseDaoTestCase {<br>
&gt; &gt;<br>
&gt; &gt; @Inject<br>
&gt; &gt; private VdsBuilder vdsBuilder;<br>
&gt; &gt;<br>
&gt; &gt; @Test<br>
&gt; &gt; public void createHosts() {<br>
&gt; &gt; VdsBuilder builder =<br>
&gt; &gt; vdsBuilder.cluster(persistedCluster).physicalMemory(1000);<br>
&gt; &gt; for (int x =0; x &lt; 10; x++){<br>
&gt; &gt; <a href="http://builder.id" rel="noreferrer" target="_blank">builder.id</a> (Guid.newGuid()).persist();<br>
&gt; &gt; }<br>
&gt; &gt; }<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; 3) Full integration test with arquillian and the database<br>
&gt; &gt;<br>
&gt; &gt; @Category(IntegrationTest.class)<br>
&gt; &gt; public class VmDaoIntegrationTest extends TransactionalTestBase {<br>
&gt; &gt;<br>
&gt; &gt; @Inject<br>
&gt; &gt; VmDao vmDao;<br>
&gt; &gt;<br>
&gt; &gt; private final Guid VM1_GUID =<br>
&gt; &gt; Guid.createGuidFromString(&quot;0fe4bc81-5999-4ab6-80f8-7a4a2d4bfacd&quot;);<br>
&gt; &gt;<br>
&gt; &gt; @Deployment<br>
&gt; &gt; public static JavaArchive deploy(){<br>
&gt; &gt; return createDeployment();<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; @Test<br>
&gt; &gt; public void shouldFailOnExistingEntity() {<br>
&gt; &gt; vmBuilder.id(VM1_GUID).cluster(clusterBuilder.reset().persist()).persist();<br>
&gt; &gt; // This uses assertThat from assertj:<br>
&gt; &gt; assertThat(vmDao.get(VM1_GUID)).isNotNull();<br>
&gt; &gt; }<br>
&gt; &gt; }<br>
&gt; &gt;<br>
&gt; &gt; 4) Using the builders in a normal unit test without a database:<br>
&gt; &gt;<br>
&gt; &gt; VM vm = new VmBuilder().id(Guid.newGuid()).up().build();<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; # How to add your own Domain objects?<br>
&gt; &gt;<br>
&gt; &gt; There are just a few simple rules:<br>
&gt; &gt;<br>
&gt; &gt; 1) Your builder should extend org.ovirt.engine.core.builder.AbstractBuilder<br>
&gt; &gt;<br>
&gt; &gt; 2) Make sure that you only access DAOs injected into the builder during<br>
&gt; &gt; #prePersist() and #persist(). This allows to use the #build() method also<br>
&gt; &gt; without injections<br>
&gt; &gt;<br>
&gt; &gt; 3) #prePersist() should set all fields which are necessary to suffice<br>
&gt; &gt; database constraints. The fields should only be set if they are not already<br>
&gt; &gt; set before by the builder. When following this rule we can always persist<br>
&gt; &gt; new objects to the database by simply calling myBuilder.reset().persist().<br>
&gt; &gt;<br>
&gt; &gt; 4) Mark your builder with @Repository to make them useable for our Spring<br>
&gt; &gt; DAO<br>
&gt; &gt; tests and our Arquillian integration tests.<br>
&gt; &gt;<br>
&gt; &gt; So have a look at the patches at [1] and let me know what you think about<br>
&gt; &gt; them.<br>
&gt; &gt;<br>
&gt; &gt; Best Regards and happy testing,<br>
&gt; &gt;<br>
&gt; &gt; Roman<br>
&gt; &gt;<br>
&gt; &gt; [1] <a href="https://gerrit.ovirt.org/#/q/topic:integration" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/#/q/topic:integration</a><br>
&gt; &gt; [2] <a href="https://gerrit.ovirt.org/#/c/47008/17" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/#/c/47008/17</a><br>
&gt; &gt; [3] <a href="https://gerrit.ovirt.org/#/c/47007/10" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/#/c/47007/10</a><br>
&gt; &gt; [4] <a href="https://gerrit.ovirt.org/#/c/47008/17" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/#/c/47008/17</a><br>
&gt; &gt; [5] <a href="https://maven.apache.org/surefire/maven-failsafe-plugin/" rel="noreferrer" target="_blank">https://maven.apache.org/surefire/maven-failsafe-plugin/</a><br>
&gt; &gt;<br>
&gt; &gt; _______________________________________________<br>
&gt; &gt; Devel mailing list<br>
&gt; &gt; <a href="mailto:Devel@ovirt.org">Devel@ovirt.org</a><br>
&gt; &gt; <a href="http://lists.ovirt.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.ovirt.org/mailman/listinfo/devel</a><br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; --<br>
&gt; &gt; Eyal Edri<br>
&gt; &gt; Associate Manager<br>
&gt; &gt; RHEV DevOps<br>
&gt; &gt; EMEA ENG Virtualization R&amp;D<br>
&gt; &gt; Red Hat Israel<br>
&gt; &gt;<br>
&gt; &gt; phone: <a href="tel:%2B972-9-7692018" value="+97297692018">+972-9-7692018</a><br>
&gt; &gt; irc: eedri (on #tlv #rhev-dev #rhev-integ)<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; _______________________________________________<br>
&gt; &gt; Devel mailing list<br>
&gt; &gt; <a href="mailto:Devel@ovirt.org">Devel@ovirt.org</a><br>
&gt; &gt; <a href="http://lists.ovirt.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.ovirt.org/mailman/listinfo/devel</a><br>
&gt; _______________________________________________<br>
&gt; Devel mailing list<br>
&gt; <a href="mailto:Devel@ovirt.org">Devel@ovirt.org</a><br>
&gt; <a href="http://lists.ovirt.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.ovirt.org/mailman/listinfo/devel</a><br>
&gt;<br>
</div></div></blockquote></div><br>[6] <a href="https://projectlombok.org/features/Builder.html">https://projectlombok.org/features/Builder.html</a><br></div></div>