Skip to content

Commit

Permalink
Added benchmarks for batchUpdate
Browse files Browse the repository at this point in the history
For #382 - added benchmarks for RPM batchUpdate
metadata generator.

PR: #383
  • Loading branch information
g4s8 authored Apr 16, 2021
1 parent b0b0ebc commit 88c513f
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ target/
.classpath
.project
src/test/resources-binary/rpms/**
.factorypath
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,13 @@ $ mvn clean install -Pqulice
```

To avoid build errors use Maven 3.2+.

## Benchmarking

To run benchmarks:
1. Build `rpm-adapter` with `bench` Maven profile enabled: `mvn package -Pbench`
2. Copy dependencies to `target/` dir: `mvn dependency:copy-dependencies`
3. Create directory for tests and copy test resources to this directory; RPM bundles available:
- https://artipie.s3.amazonaws.com/rpm-test/bundle100.tar.gz
- https://artipie.s3.amazonaws.com/rpm-test/bundle1000.tar.gz
4. Run benchmarks with `env BENCH_DIR=/tmp/rpm-test java -cp "target/benchmarks.jar:target/classes/*:target/dependency/*" org.openjdk.jmh.Main RpmBench`, where `/tmp/rpm-test` is a directory with RPM packages for tests.
75 changes: 75 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ SOFTWARE.
<description>Turns your files/objects into RPM artifacts</description>
<url>https://github.com/artipie/rpm-adapter</url>
<inceptionYear>2019</inceptionYear>
<properties>
<jmh.version>1.29</jmh.version>
</properties>
<licenses>
<license>
<name>MIT</name>
Expand Down Expand Up @@ -212,6 +215,16 @@ SOFTWARE.
<version>1.7.30</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
</dependencies>
<build>
<testResources>
Expand Down Expand Up @@ -320,6 +333,9 @@ SOFTWARE.
</limits>
</rule>
</rules>
<excludes>
<exclude>com/artipie/rpm/benchmarks/**/*</exclude>
</excludes>
</configuration>
</execution>
<execution>
Expand Down Expand Up @@ -387,5 +403,64 @@ SOFTWARE.
</plugins>
</build>
</profile>
<profile>
<id>bench</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>benchmarks</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<filters>
<filter>
<!--
Shading signed JARs will fail without this.
http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
-->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
<configuration>
<includeScope>runtime</includeScope>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
83 changes: 83 additions & 0 deletions src/main/java/com/artipie/rpm/benchmarks/RpmBench.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 artipie.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package com.artipie.rpm.benchmarks;

import com.artipie.asto.Key;
import com.artipie.asto.Storage;
import com.artipie.asto.fs.FileStorage;
import com.artipie.rpm.Rpm;
import hu.akarnokd.rxjava2.interop.CompletableInterop;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

/**
* Benchmark for {@link RPM}.
* @since 1.4
* @checkstyle MagicNumberCheck (500 lines)
* @checkstyle DesignForExtensionCheck (500 lines)
* @checkstyle JavadocMethodCheck (500 lines)
*/
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Warmup(iterations = 5)
@Measurement(iterations = 50)
public class RpmBench {

/**
* Benchmark directory.
*/
private static final String BENCH_DIR = System.getenv("BENCH_DIR");

/**
* Repository storage.
*/
private Storage storage;

@Setup
public void setup() {
if (RpmBench.BENCH_DIR == null) {
throw new IllegalStateException("BENCH_DIR environment variable must be set");
}
this.storage = new FileStorage(Paths.get(RpmBench.BENCH_DIR));
}

@Benchmark
public void run(final Blackhole bhl) {
new Rpm(this.storage).batchUpdate(Key.ROOT)
.to(CompletableInterop.await())
.toCompletableFuture().join();
}
}
29 changes: 29 additions & 0 deletions src/main/java/com/artipie/rpm/benchmarks/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 artipie.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/**
* RPM benchmarks.
* @since 1.4
*/
package com.artipie.rpm.benchmarks;

1 comment on commit 88c513f

@0pdd
Copy link

@0pdd 0pdd commented on 88c513f Apr 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to retrieve PDD puzzles from the code base and submit them to GitHub. If you think that it's a bug on our side, please submit it to yegor256/0pdd:

XML has 1 errors w73:0: ERROR: Element 'email': [facet 'pattern'] The value '49699333+dependabot[bot]@users.noreply.github.com' is not accepted by the pattern '(0-9a-zA-Z@([0-9a-zA-Z][-\w][0-9a-zA-Z].)+[a-zA-Z]{2,9})'. <puzzles...

Please, copy and paste this stack trace to GitHub:

RuntimeError
XML has 1 errors
w73:0: ERROR: Element 'email': [facet 'pattern'] The value '49699333+dependabot[bot]@users.noreply.github.com' is not accepted by the pattern '([0-9a-zA-Z]([-_.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})'.
<?xml version="1.0"?>
<puzzles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.0pdd.com/puzzles.xsd" date="2020-10-27T07:50:18+00:00" version="0.30.21">
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/32" closed="2020-03-13T08:09:02+00:00">32</issue>
    <ticket>30</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>30-6f533735</id>
    <lines>52-56</lines>
    <body>Refactor this test. Convert it to Junit5 and use `TempDir` extension, refactor same logic for extracting rpm file from resources, get rid of multi-threading in matcher, simplify the test, test only one thing in each unit test (split test to multiple if needed). Also, remove supressed PMD warning.</body>
    <file>src/test/java/com/artipie/rpm/RpmTest.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-03-10T14:36:13Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/40" closed="2020-04-08T17:29:15+00:00">40</issue>
        <ticket>32</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>32-75a1be06</id>
        <lines>54-56</lines>
        <body>This test class needs refactoring. What is still need to be done is to get rid of multi-threading in matcher, to simplify the test, and to test only one thing in each unit test (split test to multiple if needed).</body>
        <file>src/test/java/com/artipie/rpm/RpmTest.java</file>
        <author>HDouss</author>
        <email>douss.hamdi@gmail.com</email>
        <time>2020-03-12T09:29:07Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/41" closed="2020-04-02T09:04:13+00:00">41</issue>
    <ticket>29</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>29-399d2455</id>
    <lines>166-170</lines>
    <body>Refactor Repomd.performUpdate method. It was hot-fixed by adding additional required parameters, it's hard to read and understand without reading the whole code. Most probably this method can be split into multiple methods or some parts can be moved to another class.</body>
    <file>src/main/java/com/artipie/rpm/Repomd.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-03-13T08:34:47Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/60" closed="2020-04-08T17:29:22+00:00">60</issue>
        <ticket>41</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>41-df9cd1a3</id>
        <lines>142-146</lines>
        <body>Continue refactoring Repomd.performUpdate method and all other dependencies: it is very long and complex to read and understand without reading everything. The content of the zipWith below should be extracted in its own method. If possible make it a class that can be tested by itself.</body>
        <file>src/main/java/com/artipie/rpm/Repomd.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-02T07:47:32Z</time>
        <children/>
      </puzzle>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/61" closed="2020-04-08T17:29:28+00:00">61</issue>
        <ticket>41</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>41-ab144851</id>
        <lines>191-194</lines>
        <body>This method and saveGzip are very similar but implemented differently. Factor those together as the same method based on the implementation of the saveGzip that is closer to the rx paradigm than saveRepo.</body>
        <file>src/main/java/com/artipie/rpm/Repomd.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-03-31T18:50:52Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/70" closed="2020-04-08T17:29:34+00:00">70</issue>
    <ticket>17</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>17-f66e78ab</id>
    <lines>34-37</lines>
    <body>Implement WithFilelists decorator. WithFilelists decorator create filelists.xml and filelists.xml.gz files on upload. Implement this behavior and then enable the test in WithFilelistsTest.</body>
    <file>src/main/java/com/artipie/rpm/WithFilelists.java</file>
    <author>paulodamaso</author>
    <email>pauloeduardolobo@gmail.com</email>
    <time>2020-03-24T03:06:18Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/75" closed="2020-04-29T12:22:11+00:00">75</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-3c6bbf6c</id>
    <lines>113-115</lines>
    <body>Create unit tests to verify that FilePackage headers can parse headers and header range correctly, can calculate file size and check-sums correctly.</body>
    <file>src/main/java/com/artipie/rpm/pkg/FilePackage.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/154" closed="2020-06-30T11:32:28+00:00">154</issue>
        <ticket>75</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>75-9baf1976</id>
        <lines>50-55</lines>
        <body>Create tests to validate that FilePackage, given a rpm file and a PackageOutput, correctly parse the file. The main objective here is to validate that parsing of rpm file is happening correctly, so the chosen PackageOutput should do something with Package.Meta to exercise the parsing of the file.</body>
        <file>src/main/java/com/artipie/rpm/pkg/FilePackage.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-28T08:37:15Z</time>
        <children/>
      </puzzle>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/155" closed="2020-05-20T09:57:42+00:00">155</issue>
        <ticket>75</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>75-58eafec8</id>
        <lines>38-42</lines>
        <body>Transform the parseStringHeader test below to a parameterized test that test each of the asXXX method of MetaHeader with two test method: one for the tag being present and one for when it is absent (and default value is returned).</body>
        <file>src/test/java/com/artipie/rpm/pkg/FilePackageHeadersTest.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-28T08:37:15Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/76" closed="2020-04-13T07:49:42+00:00">76</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-5a24f18b</id>
    <lines>33-34</lines>
    <body>Write javadocs for all these method. When done, remove JavadocMethodCheck suppression annotation for PMD checker.</body>
    <file>src/main/java/com/artipie/rpm/pkg/HeaderTags.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/77" closed="2020-04-15T12:22:24+00:00">77</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-56010550</id>
    <lines>49-50</lines>
    <body>This class has too many methods, consider refactoring it. Most probably headers methods can be moved to another Headers (or Tags) object.</body>
    <file>src/main/java/com/artipie/rpm/pkg/Package.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/78" closed="2020-04-13T14:25:34+00:00">78</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-b66a2919</id>
    <lines>45-46</lines>
    <body>Add a unit test for this class, it should verify that it updates `repomd.xml` file correctly after save.</body>
    <file>src/main/java/com/artipie/rpm/pkg/MetadataFile.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/106" closed="2020-05-26T12:24:43+00:00">106</issue>
        <ticket>78</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>78-ae125758</id>
        <lines>43-47</lines>
        <body>This test has everything setup so that the file corresponding to the fake wrapped FileOutput is actually included in the repomd.xml file. This test now should verify that it updates `repomd.xml` file correctly after save. If #101 is solved, remove the DisabledOnOs annotation.</body>
        <file>src/test/java/com/artipie/rpm/pkg/MetadataFileTest.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-11T15:35:57Z</time>
        <children>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/206" closed="2020-06-01T10:48:13+00:00">206</issue>
            <ticket>106</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>106-c1f3bb3a</id>
            <lines>45-53</lines>
            <body>MetadataFile is saving an invalid xml to repomd.xml. This test verifies that MetadataFile updates `repomd.xml` file correctly after save, but it doesn't. Fix it then enable the test, restoring the coverage levels to: instructions: 0.36 lines: 0.42 complexity: 0.38 methods: 0.35 missed classes: 16.</body>
            <file>src/test/java/com/artipie/rpm/pkg/MetadataFileTest.java</file>
            <author>paulodamaso</author>
            <email>pauloeduardolobo@gmail.com</email>
            <time>2020-05-13T01:24:36Z</time>
            <children/>
          </puzzle>
        </children>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/79" closed="2020-04-20T13:55:47+00:00">79</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-a899429c</id>
    <lines>67-71</lines>
    <body>Add option to exclude `filelists.xml` metadata file from updates. Som RPM repositories contains too many files in RPM packages, so it may take too many time to update the filelists. Just add an option to `Rpm` constructor and exclude filelists output from `Repository` list of metadata files in `batchUpdate` method.</body>
    <file>src/main/java/com/artipie/rpm/Rpm.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/129" closed="2020-05-18T14:23:23+00:00">129</issue>
        <ticket>79</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>79-4e9f7178</id>
        <lines>68-69</lines>
        <body>Right now Rpm always includes filelists - the flag is hard-coded to true. Let's make it a command line option to pass to the Rpm class.</body>
        <file>src/main/java/com/artipie/rpm/Cli.java</file>
        <author>@g4s8</author>
        <email>g4s8.public@gmail.com</email>
        <time>2020-04-20T13:55:32Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/80" closed="2020-04-20T13:55:54+00:00">80</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-0165dd8a</id>
    <lines>53-55</lines>
    <body>Create a unit test to verify that this class can write `others.xml` file correctly. The example of others.xml can be found at test resources.</body>
    <file>src/main/java/com/artipie/rpm/meta/XmlOthers.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/130" closed="2020-05-19T15:57:02+00:00">130</issue>
        <ticket>80</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>80-4f54b460</id>
        <lines>39-41</lines>
        <body>add another test for adding a changelog to do that you need to wait for the changelog to be implemented first there's a puzzle for implementing it.</body>
        <file>src/test/java/com/artipie/rpm/meta/XmlOthersTest.java</file>
        <author>Kirill</author>
        <email>g4s8.public@gmail.com</email>
        <time>2020-04-20T13:55:32Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/81" closed="2020-04-13T12:13:19+00:00">81</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-30c26981</id>
    <lines>168-170</lines>
    <body>Refactor XML classes. Each XML writer (XmlOthers, XmlPrimary, XmlFilelists, XmlRepomd) has similar code to construct new stream writer using factory. Let's refactor this somehow.</body>
    <file>src/main/java/com/artipie/rpm/meta/XmlOthers.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/103" closed="2020-04-18T19:17:54+00:00">103</issue>
        <ticket>81</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>81-827d5ef1</id>
        <lines>49-51</lines>
        <body>Introduce an envelope for XMLStreamWriter so that XmlFile can extend it and wrap the XMLStreamWriter created in the constructor instead of exposing its internal state via the writer() method.</body>
        <file>src/main/java/com/artipie/rpm/meta/XmlFile.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-11T09:35:08Z</time>
        <children/>
      </puzzle>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/104" closed="2020-04-27T06:37:56+00:00">104</issue>
        <ticket>81</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>81-27d531fb</id>
        <lines>52-60</lines>
        <body>Introduce a new class named XmlPackagesFile that should be responsible of writing the start of the document (as in {XmlFilelists, XmlOthers, XmlPrimary}.startPackages and XmlRepomd.begin) as well as writing the end of the document (as in {XmlFilelists, XmlOthers, XmlPrimary}.close) by taking the needed information in its constructor + a XmlFile. It should also be responsible of counting the number of packages added. With all this information, the alter method can then be moved to XmlPackagesFile and renamed close by exploiting directly that information. Once it is done, use XmlPackagesFile in XmlFilelists, XmlOthers, XmlPrimary and keep using XmlFile in XmlRepomd.</body>
        <file>src/main/java/com/artipie/rpm/meta/XmlFile.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-13T11:51:02Z</time>
        <children>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/147" closed="2020-05-08T07:54:46+00:00">147</issue>
            <ticket>104</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>104-6e11be90</id>
            <lines>36-38</lines>
            <body>XmlPackagesFile is now used in XmlOthers and XmlFilelists. Add a support for additional namespaces (in addition to the default namespace) so it can be used in XmlPrimary as well.</body>
            <file>src/main/java/com/artipie/rpm/meta/XmlPackagesFile.java</file>
            <author>Kirill</author>
            <email>g4s8.public@gmail.com</email>
            <time>2020-04-27T06:37:43Z</time>
            <children/>
          </puzzle>
        </children>
      </puzzle>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/105" closed="2020-06-17T18:04:32+00:00">105</issue>
        <ticket>81</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>81-6d01bf6b</id>
        <lines>43-51</lines>
        <body>Refactor this class so it uses XmlFile instead of using a XMLStreamWriter and a Path. It is not straightforward because it exposes the Path via the path() which is now hidden in the XmlFile object. We must keep the path hidden there while at the same time allow for Repository to be responsible of triggering the save of the repomd file after all the metadata files (declared in Rpm) have wrote themselves to repomd as expected. One solution would be to delegate to the xml files and thus to XmlFile the act of moving itself in the desired place: in that case the way other metadata files are saved should be adapted.</body>
        <file>src/main/java/com/artipie/rpm/meta/XmlRepomd.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-11T09:35:08Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/82" closed="2020-05-20T06:35:12+00:00">82</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-43c6c36b</id>
    <lines>231-233</lines>
    <body>Implement changelog method. It's not clear how exaclty it should be extracted from package headers. Check example RPM packages in test bin resources and `other.xml` file for this file in test resources.</body>
    <file>src/main/java/com/artipie/rpm/meta/XmlOthers.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/191" closed="2020-06-10T16:48:08+00:00">191</issue>
        <ticket>82</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>82-4bfb0748</id>
        <lines>151-156</lines>
        <body>Continue changelog implementation. Changelog info is composed of a sequence of entries (as seen in https://rpm-packaging-guide.github.io/#packaging-software ,changelog section). This information will be extracted from package headers and sent here to be parsed and added to the others.xml file. After implementing this enable test on XmlOthersTest.</body>
        <file>src/main/java/com/artipie/rpm/meta/XmlOthers.java</file>
        <author>paulodamaso</author>
        <email>pauloeduardolobo@gmail.com</email>
        <time>2020-05-13T17:51:44Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/83" closed="2020-04-15T12:14:08+00:00">83</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-e192dc9a</id>
    <lines>58-60</lines>
    <body>Create a unit test to verify that this class can write `primary.xml` file correctly. The example of primary.xml can be found at test resources.</body>
    <file>src/main/java/com/artipie/rpm/meta/XmlPrimary.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/117" closed="2020-06-02T15:48:30+00:00">117</issue>
        <ticket>83</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>83-a430163f</id>
        <lines>38-42</lines>
        <body>This test only creates a temporary file for XmlPrimary, now some assertion should be added to verify that this class can write `primary.xml` file correctly. The example of primary can be found at test resources. If #86 is fixed then remove the DisabledOnOs annotation.</body>
        <file>src/test/java/com/artipie/rpm/meta/XmlPrimaryTest.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-11T09:20:54Z</time>
        <children>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/219" closed="2020-06-10T14:06:59+00:00">219</issue>
            <ticket>117</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>117-c6ba630d</id>
            <lines>43-47</lines>
            <body>Fix metadata 'packages' attribute XmlPrimary is generating 'packages' attribute in 'metadata' element with the wrong value. Correct this (it should reflect the number of packages described in primary.xml file) and then add a check to this value on XmlPrimaryTest.</body>
            <file>src/main/java/com/artipie/rpm/meta/XmlPrimary.java</file>
            <author>paulodamaso</author>
            <email>pauloeduardolobo@gmail.com</email>
            <time>2020-05-25T22:24:43Z</time>
            <children/>
          </puzzle>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/220" closed="2020-06-11T08:08:55+00:00">220</issue>
            <ticket>117</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>117-c0f32a4a</id>
            <lines>48-54</lines>
            <body>Fix 'provides' element generation XmlPrimary is not generating 'provides' elements correctly. Actually it does not generate a 'provides' element at all: it should generate an element named 'provides' with child entries containing 'name', 'flags', 'epoch' and 'ver' attributes. Refer to primary.xml.example file for more details. The test in XmlPrimaryTest must be updated once 'provides' element generation is fixed.</body>
            <file>src/main/java/com/artipie/rpm/meta/XmlPrimary.java</file>
            <author>paulodamaso</author>
            <email>pauloeduardolobo@gmail.com</email>
            <time>2020-05-25T22:24:43Z</time>
            <children>
              <puzzle alive="false">
                <issue href="https://github.com/artipie/rpm-adapter/issues/254" closed="2020-09-24T07:47:56+00:00">254</issue>
                <ticket>220</ticket>
                <estimate>30</estimate>
                <role>DEV</role>
                <id>220-c707f9f7</id>
                <lines>432-439</lines>
                <body>We need to experimentally check that names and versions do not mix up in `provides`: download oxygen-gtk2-1.3.4-3.el7.x86_64.rpm from test bundle100 (see TestBundle.class), add it to resources folder and create xml primary from it. This rpm has not full `provides` information: &lt;rpm:entry name="liboxygen-gtk.so()(64bit)"/&gt; &lt;rpm:entry name="oxygen-gtk2" flags="EQ" epoch="0" ver="1.3.4" rel="3.el7"/&gt; &lt;rpm:entry name="oxygen-gtk2(x86-64)" flags="EQ" epoch="0" ver="1.3.4" rel="3.el7"/&gt; Make sure we write it the same way.</body>
                <file>src/main/java/com/artipie/rpm/meta/XmlPrimary.java</file>
                <author>@olenagerasimova</author>
                <email>olena.gerasimova@gmail.com</email>
                <time>2020-06-03T09:57:35Z</time>
                <children/>
              </puzzle>
              <puzzle alive="true">
                <issue href="https://github.com/artipie/rpm-adapter/issues/255">255</issue>
                <ticket>220</ticket>
                <estimate>30</estimate>
                <role>DEV</role>
                <id>220-dd2fed2e</id>
                <lines>440-442</lines>
                <body>Provides entry also can have `flags`, `epoch` and `rel` attributes. Find a way to obtain this information from rpm and add it here. Do not forget about test.</body>
                <file>src/main/java/com/artipie/rpm/meta/XmlPrimary.java</file>
                <author>@olenagerasimova</author>
                <email>olena.gerasimova@gmail.com</email>
                <time>2020-06-03T18:54:10Z</time>
                <children/>
              </puzzle>
              <puzzle alive="true">
                <issue href="https://github.com/artipie/rpm-adapter/issues/366">366</issue>
                <ticket>220</ticket>
                <estimate>30</estimate>
                <role>DEV</role>
                <id>220-a8f07415</id>
                <lines>432-439</lines>
                <body>We need to experimentally check that names and versions do not mix up in `provides`: download oxygen-gtk2-1.3.4-3.el7.x86_64.rpm from test bundle100 (see TestBundle.class), add it to resources folder and create xml primary from it. This rpm has not full `provides` information, entry tags are: - rpm:entry name="liboxygen-gtk.so()(64bit)" - rpm:entry name="oxygen-gtk2" flags="EQ" epoch="0" ver="1.3.4" rel="3.el7" - rpm:entry name="oxygen-gtk2(x86-64)" flags="EQ" epoch="0" ver="1.3.4" rel="3.el7" Make sure we write it the same way.</body>
                <file>src/main/java/com/artipie/rpm/meta/XmlPrimary.java</file>
                <author>@olenagerasimova</author>
                <email>olena.gerasimova@gmail.com</email>
                <time>2020-08-05T14:23:18Z</time>
                <children/>
              </puzzle>
            </children>
          </puzzle>
        </children>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/84" closed="2020-04-13T16:26:25+00:00">84</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-64696d73</id>
    <lines>55-57</lines>
    <body>Create a unit test to verify that this class can write `filelists.xml` file correctly. The example of filelists can be found at test resources.</body>
    <file>src/main/java/com/artipie/rpm/meta/XmlFilelists.java</file>
    <author>Kirill</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/107" closed="2020-05-19T06:13:38+00:00">107</issue>
        <ticket>84</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>84-f98fbe90</id>
        <lines>38-42</lines>
        <body>This test only creates a temporary file for XmlFilelists, now some assertion should be added to verify that this class can write `filelists.xml` file correctly. The example of filelists can be found at test resources. If #86 is fixed then remove the DisabledOnOs annotation.</body>
        <file>src/test/java/com/artipie/rpm/meta/XmlFilelistsTest.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-04-11T08:46:35Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/85" closed="2020-05-08T06:44:06+00:00">85</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-ac25d152</id>
    <lines>41-48</lines>
    <body>I've checked that this test generates metadata correctly, but we need to automate it. Let's check all metadata files after `Rpm.batchUpdate()` using xpath matchers. The files to check: primary.xml, others.xml, filelists.xml, repomd.xml. These files are stored in storage at path: `repomd/SHA1-TYPE.xml.gz`, where SHA1 is a HEX from SHA1 of file content and TYPE is a type of file (primary, others, filelists). Don't forget to uncompress it first. repomd.xml is not compressed and stored at `repodata/repomd.xml`.</body>
    <file>src/test/java/com/artipie/rpm/RpmITCase.java</file>
    <author>Kirill</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:07:04Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/166" closed="2020-07-02T08:50:17+00:00">166</issue>
        <ticket>85</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>85-d051fc3e</id>
        <lines>47-52</lines>
        <body>Continue the automation of batchUpdate tests. We still need to check the files to check primary.xml, others.xml and filelists.xml. These files are stored in storage at path: `repomd/SHA1-TYPE.xml.gz`, where SHA1 is a HEX from SHA1 of file content and TYPE is a type of file (primary, others, filelists). Don't forget to uncompress it first.</body>
        <file>src/test/java/com/artipie/rpm/RpmITCase.java</file>
        <author>paulodamaso</author>
        <email>pauloeduardolobo@gmail.com</email>
        <time>2020-04-30T05:19:08Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/86" closed="2020-04-16T06:59:11+00:00">86</issue>
    <ticket>69</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>69-20779ab6</id>
    <lines>49-52</lines>
    <body>This test is failing on Windows build. It's failing because of error FileAlreadyExistException in PrimaryXml.close in Files.move, but it's using REPLACE_EXISTING options, so it should not fail and it's not failing on Linux. Let's discover the problem, fix it, and remove DisabledOnOs(OS.WINDOWS) annotation.</body>
    <file>src/test/java/com/artipie/rpm/RpmITCase.java</file>
    <author>Kirill</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-08T17:21:25Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/89" closed="2020-04-14T16:31:36+00:00">89</issue>
    <ticket>68</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>68-3d243175</id>
    <lines>83-87</lines>
    <body>start execution of the command you can use cmd.getArgs() to get args as array of strings you would expect something like ["update", "./package.rpm"] use this link for documentation https://commons.apache.org/proper/commons-cli/usage.html</body>
    <file>src/main/java/com/artipie/rpm/Cli.java</file>
    <author>@ammaratef45</author>
    <email>ammar.atef45@gmail.com</email>
    <time>2020-04-09T11:38:56Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/113" closed="2020-05-26T09:51:33+00:00">113</issue>
        <ticket>89</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>89-bf69222b</id>
        <lines>41-43</lines>
        <body>Cli options are not parsed correctly. getOptionValue method always return default value for both options, so it's not possible to override them. But the tool is working correctly. To build it use `cli` maven profile, see the README.</body>
        <file>src/main/java/com/artipie/rpm/Cli.java</file>
        <author>@g4s8</author>
        <email>g4s8.public@gmail.com</email>
        <time>2020-04-09T13:09:51Z</time>
        <children>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/205" closed="2020-06-02T15:47:44+00:00">205</issue>
            <ticket>113</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>113-cf87a1eb</id>
            <lines>36-38</lines>
            <body>Add more tests for CliArgumentTests. Add tests for CliArguments using all arguments, '=' signal for setting argument values and longopt name arguments.</body>
            <file>src/test/java/com/artipie/rpm/CliArgumentsTest.java</file>
            <author>paulodamaso</author>
            <email>pauloeduardolobo@gmail.com</email>
            <time>2020-05-25T19:25:20Z</time>
            <children/>
          </puzzle>
        </children>
      </puzzle>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/114" closed="2020-05-13T07:31:39+00:00">114</issue>
        <ticket>89</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>89-d55308e3</id>
        <lines>65-67</lines>
        <body>Refactor options parsing. Extract the logic of parsing CLI arguments into separate class with methods like naming, digest, path.</body>
        <file>src/main/java/com/artipie/rpm/Cli.java</file>
        <author>@g4s8</author>
        <email>g4s8.public@gmail.com</email>
        <time>2020-04-13T10:51:44Z</time>
        <children>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/176" closed="2020-06-29T04:51:56+00:00">176</issue>
            <ticket>114</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>114-f9d288ae</id>
            <lines>34-35</lines>
            <body>Add some more tests in order to validate the all the assumptions made in Cli and in CliArguments.</body>
            <file>src/test/java/com/artipie/rpm/CliTest.java</file>
            <author>Victor No&#xEB;l</author>
            <email>victor.noel@crazydwarves.org</email>
            <time>2020-05-08T15:13:57Z</time>
            <children/>
          </puzzle>
        </children>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/135" closed="2020-04-24T14:45:02+00:00">135</issue>
    <ticket>124</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>124-5bce57f2</id>
    <lines>36-38</lines>
    <body>Modify this class and XmlFilelists to be able to work with already existing filelists.xml: we need to accept this this xml data about new packages and delete data about package by package id (checksum). Do fot forget about tests.</body>
    <file>src/main/java/com/artipie/rpm/pkg/FilelistsOutput.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-22T10:13:39Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/136" closed="2020-04-24T14:45:08+00:00">136</issue>
    <ticket>124</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>124-3102e87b</id>
    <lines>36-38</lines>
    <body>Modify this class and XmlOthers to be able to work with already existing others.xml: we need to accept this this xml data about new packages and delete data about package by package id (checksum). Do fot forget about tests.</body>
    <file>src/main/java/com/artipie/rpm/pkg/OthersOutput.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-22T10:13:39Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/143" closed="2020-05-13T07:31:46+00:00">143</issue>
        <ticket>136</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>136-9d5dbc04</id>
        <lines>36-37</lines>
        <body>Make this class be able to work this already existing filelists.xml by adding corresponding ctor and test it.</body>
        <file>src/main/java/com/artipie/rpm/pkg/FilelistsOutput.java</file>
        <author>olenagerasimova</author>
        <email>olena.gerasimova@gmail.com</email>
        <time>2020-04-24T11:53:08Z</time>
        <children/>
      </puzzle>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/144" closed="2020-05-08T06:44:11+00:00">144</issue>
        <ticket>136</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>136-d4e1ea38</id>
        <lines>44-47</lines>
        <body>We need to use this interface to clear metadata from not existing packages. Implement it in the following steps: 1) make XmlPrimaryMaid implement this interface too, 2) add it as a field to ModifiableMetadata, 3) find a way to correct packages count after clearing it (method XmlFile#alterTag() does it)</body>
        <file>src/main/java/com/artipie/rpm/meta/XmlMaid.java</file>
        <author>olenagerasimova</author>
        <email>olena.gerasimova@gmail.com</email>
        <time>2020-04-24T11:53:08Z</time>
        <children>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/167" closed="2020-05-13T07:31:52+00:00">167</issue>
            <ticket>144</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>144-e68f383c</id>
            <lines>45-46</lines>
            <body>Create separate proper unit-test for this class, now it is tested in the XmlPackagesFileTest#writesCorrectPackageCount(java.nio.file.Path) method.</body>
            <file>src/main/java/com/artipie/rpm/meta/XmlAlter.java</file>
            <author>olenagerasimova</author>
            <email>olena.gerasimova@gmail.com</email>
            <time>2020-05-07T08:39:18Z</time>
            <children/>
          </puzzle>
        </children>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/137" closed="2020-05-08T06:44:17+00:00">137</issue>
    <ticket>124</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>124-752857bc</id>
    <lines>52-56</lines>
    <body>Implement this method to extract from metadata files data about packages that are already not presented if the repository. This should be done after PrimaryOutput, FilelistsOutput and OthersOutput will be able to modify their packages. Also when this method will be implemented, rpm.Rpm#updateBatchIncrementally(com.artipie.asto.Key) and use this method to update repos.</body>
    <file>src/main/java/com/artipie/rpm/pkg/ModifiableMetadata.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-22T10:13:39Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/138" closed="2020-04-24T10:38:38+00:00">138</issue>
    <ticket>124</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>124-6b3b1cde</id>
    <lines>36-38</lines>
    <body>Modify this class and XmlPrimary to be able to work with already existing primary.xml: we need to accept this this xml data about new packages and delete data about package by package id (checksum). Do fot forget about tests.</body>
    <file>src/main/java/com/artipie/rpm/pkg/PrimaryOutput.java</file>
    <author>@g4s8</author>
    <email>g4s8.public@gmail.com</email>
    <time>2020-04-22T10:13:39Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/141" closed="2020-05-13T07:31:58+00:00">141</issue>
        <ticket>138</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>138-e82cce42</id>
        <lines>36-37</lines>
        <body>Make this class be able to work this already existing primary by adding corresponding ctor and test it.</body>
        <file>src/main/java/com/artipie/rpm/pkg/PrimaryOutput.java</file>
        <author>olenagerasimova</author>
        <email>olena.gerasimova@gmail.com</email>
        <time>2020-04-22T19:46:01Z</time>
        <children>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/177" closed="2020-05-20T10:10:24+00:00">177</issue>
            <ticket>141</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>141-769c95ee</id>
            <lines>38-40</lines>
            <body>Create tests for this class: we need standard unit test and IT Case long test, which will use large xml from test bundles (I guess we can simply join meta-xml from hundred and thousand rpm bundles).</body>
            <file>src/main/java/com/artipie/rpm/pkg/ModifiableMetadata.java</file>
            <author>@olenagerasimova</author>
            <email>olena.gerasimova@gmail.com</email>
            <time>2020-05-12T05:17:59Z</time>
            <children/>
          </puzzle>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/178" closed="2020-05-20T07:09:01+00:00">178</issue>
            <ticket>141</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>141-85a28213</id>
            <lines>233-238</lines>
            <body>Finish incremental update: we need to obtain meta-files from repository we are updating, these files are stored in `repodata` folder, are gziped (use Gzip to unzip), their names are [file-checksum]-metafile.xml.gz. Then add test to RpmITCase to check that this method works. After that we can think about further optimization: for example we can read xml primary checksums and copy rpms at the same time in different threads.</body>
            <file>src/main/java/com/artipie/rpm/Rpm.java</file>
            <author>@olenagerasimova</author>
            <email>olena.gerasimova@gmail.com</email>
            <time>2020-05-12T05:17:59Z</time>
            <children>
              <puzzle alive="false">
                <issue href="https://github.com/artipie/rpm-adapter/issues/192" closed="2020-06-03T08:47:22+00:00">192</issue>
                <ticket>178</ticket>
                <estimate>30</estimate>
                <role>DEV</role>
                <id>178-1f21b2fa</id>
                <lines>333-334</lines>
                <body>Try to get rid of blocking operations here, at the same time keep in mind that we need list of the existing rpm checksums from primary.xml to start the update.</body>
                <file>src/main/java/com/artipie/rpm/Rpm.java</file>
                <author>@olenagerasimova</author>
                <email>olena.gerasimova@gmail.com</email>
                <time>2020-05-14T06:25:04Z</time>
                <children>
                  <puzzle alive="false">
                    <issue href="https://github.com/artipie/rpm-adapter/issues/224" closed="2020-06-05T10:47:45+00:00">224</issue>
                    <ticket>192</ticket>
                    <estimate>30</estimate>
                    <role>DEV</role>
                    <id>192-3e5a54da</id>
                    <lines>241-242</lines>
                    <body>Extract repeating code from updateBatch() and this method into private methods or classes. Also try refactor this method to make it easier to read/maintain.</body>
                    <file>src/main/java/com/artipie/rpm/Rpm.java</file>
                    <author>@olenagerasimova</author>
                    <email>olena.gerasimova@gmail.com</email>
                    <time>2020-06-02T18:58:49Z</time>
                    <children/>
                  </puzzle>
                </children>
              </puzzle>
              <puzzle alive="false">
                <issue href="https://github.com/artipie/rpm-adapter/issues/193" closed="2020-05-26T12:32:02+00:00">193</issue>
                <ticket>178</ticket>
                <estimate>30</estimate>
                <role>DEV</role>
                <id>178-21b31f88</id>
                <lines>387-389</lines>
                <body>Create enum with metadata file items and get rid of string metadata names in the project and this method. Each enum item has to have at least metadata tag name and PackageOutput.FileOutput instance.</body>
                <file>src/main/java/com/artipie/rpm/Rpm.java</file>
                <author>@olenagerasimova</author>
                <email>olena.gerasimova@gmail.com</email>
                <time>2020-05-14T06:25:04Z</time>
                <children/>
              </puzzle>
            </children>
          </puzzle>
        </children>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/145" closed="2020-05-13T07:32:04+00:00">145</issue>
    <ticket>124</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>124-dbdcc472</id>
    <lines>36-37</lines>
    <body>Make this class be able to work this already existing others.xml by adding corresponding ctor and test it.</body>
    <file>src/main/java/com/artipie/rpm/pkg/OthersOutput.java</file>
    <author>olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-04-24T11:53:08Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/151" closed="2020-04-29T06:58:40+00:00">151</issue>
    <ticket>120</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>120-b9c4d61d</id>
    <lines>39-40</lines>
    <body>Create test for this class and use it in RpmITCase to download and UnpackGzip to unpack rmps from tar.gz. Use longTests profile for mentioned tests.</body>
    <file>src/test/java/com/artipie/rpm/files/DownloadBundle.java</file>
    <author>olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-04-24T17:20:18Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/168" closed="2020-06-29T13:33:13+00:00">168</issue>
    <ticket>161</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>161-ecd3feaa</id>
    <lines>257-260</lines>
    <body>Improve code coverage by writing unit-tests: each coverage counter should not be less than 75. Write unit-tests to achieve such coverage. After each iteration do not forget to correct coverage minimums and this todo to continue work.</body>
    <file>pom.xml</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-05-07T08:39:18Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/190" closed="2020-06-02T13:22:01+00:00">190</issue>
    <ticket>63</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>63-70804367</id>
    <lines>43-45</lines>
    <body>Don't change metadata when invalid package is sent. Currently Rpm is recalculating metadata when an invalid package is sent. It should not. Correct that and enable the test below.</body>
    <file>src/test/java/com/artipie/rpm/RpmTest.java</file>
    <author>paulodamaso</author>
    <email>pauloeduardolobo@gmail.com</email>
    <time>2020-05-01T03:02:47Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/218" closed="2020-06-04T07:33:58+00:00">218</issue>
        <ticket>190</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>190-d298c6d5</id>
        <lines>43-46</lines>
        <body>Don't change metadata when invalid package is sent. Currently Rpm is recalculating metadata when an invalid package is sent. It should not. Correct that and enable the test below. To do that `InvalidPackageException` should be caught when parsing packages.</body>
        <file>src/test/java/com/artipie/rpm/RpmTest.java</file>
        <author>@olegmoz</author>
        <email>oleg.mozzhechkov@gmail.com</email>
        <time>2020-06-02T12:37:38Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/194" closed="2020-05-26T12:32:08+00:00">194</issue>
    <ticket>159</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>159-8e7ac748</id>
    <lines>34-35</lines>
    <body>Find all usages of metadata files names and tags and replace them with this enum instances/usages.</body>
    <file>src/main/java/com/artipie/rpm/meta/XmlPackage.java</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-05-15T08:32:43Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/201" closed="2020-05-29T07:40:59+00:00">201</issue>
    <ticket>200</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>200-d9ed28fb</id>
    <lines>84-85</lines>
    <body>This method have to be removed or moved to `test` scope for test usages: it works much slower than the other implementation.</body>
    <file>src/main/java/com/artipie/rpm/meta/XmlMetaJoin.java</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-05-25T11:34:53Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/244" closed="2020-08-25T12:01:46+00:00">244</issue>
    <ticket>230</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>230-3a08fd65</id>
    <lines>35-38</lines>
    <body>Use this class in RPM update to prohibit parallel update of the same repository: add lock before starting the update and release it on terminate. Create instance of this class in Rpm#batchUpdate(), call lock() method and the start update. Call release() in doOnTerminate() method.</body>
    <file>src/main/java/com/artipie/rpm/misc/StorageLock.java</file>
    <author>olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-08T11:26:03Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/245" closed="2020-08-25T12:01:52+00:00">245</issue>
    <ticket>230</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>230-d8ecbde2</id>
    <lines>39-40</lines>
    <body>Consider waiting for the lock to be released instead of throwing an exception. This feature implementation should be properly discussed and planed first.</body>
    <file>src/main/java/com/artipie/rpm/misc/StorageLock.java</file>
    <author>olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-09T04:51:52Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/248" closed="2020-06-17T04:49:30+00:00">248</issue>
    <ticket>235</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>235-1ed04df5</id>
    <lines>37-40</lines>
    <body>Continue test rpms implementation: first, create `Multiple` implementation of this interface. Multiple implementation should accept several TestRpm in the ctor and put all the rpms into storage on `put`. Second, create `Invalid` implementation to add invalid package to storage. Third, find all usages of the test rpms and replace with these classes usages.</body>
    <file>src/test/java/com/artipie/rpm/TestRpm.java</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-09T18:58:24Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/265" closed="2020-06-29T04:27:00+00:00">265</issue>
        <ticket>248</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>248-3857a8d1</id>
        <lines>38-41</lines>
        <body>Add a method `name()` to this interface that returns the name of the rpm file. When it is done, update all all the test that needs this information to use this method. In particular, this should be at least done in RpmSliceITCase.</body>
        <file>src/test/java/com/artipie/rpm/TestRpm.java</file>
        <author>Victor No&#xEB;l</author>
        <email>victor.noel@crazydwarves.org</email>
        <time>2020-06-16T16:39:26Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/250" closed="2020-08-05T14:23:30+00:00">250</issue>
    <ticket>240</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>240-b0f96bd8</id>
    <lines>306-307</lines>
    <body>After https://github.com/artipie/asto/issues/201 is fixed, use SubStorage in this method and get gid of if-else statement inside flatMapCompletable.</body>
    <file>src/main/java/com/artipie/rpm/Rpm.java</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-09T07:34:29Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/253" closed="2020-06-15T06:51:48+00:00">253</issue>
    <ticket>162</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>162-efa52435</id>
    <lines>33-50</lines>
    <body>Finish implementation of RpmUpload RpmUpload should behave like the defined in https://github.com/artipie/rpm-adapter/issues/162: 1. Upload HTTP request Method: PUT URI: /package.rpm - the name of RPM package Query params: override (optional) - if true, override existing package with same name Body: RPM package data 2. Upload process User sends RPM package as PUT HTTP request with RPM data in body. RPM adapter Slice implementation should process this request, store the package in repository without changing the name. If package with same name already exist and override query param flag is not true, then return 409 error. Artipie Slice returns 202 status on success and trigger metadata update asynchronously, it should not run multiple metadata updates simultaneously. Finish the implementation and enable tests in RpmUploadTest.</body>
    <file>src/main/java/com/artipie/rpm/http/RpmUpload.java</file>
    <author>paulodamaso</author>
    <email>pauloeduardolobo@gmail.com</email>
    <time>2020-05-24T23:23:31Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/260" closed="2020-06-19T09:11:13+00:00">260</issue>
        <ticket>253</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>253-431eeb6b</id>
        <lines>48-53</lines>
        <body>Finish implementation of RpmUpload by implementing parsing of optional false by default `override` request parameter: if package with same name already exist and `override` query param flag is not true, then return 409 error. Parameter parsing should be implemented in `Request` class and tested, in `response` method we need to check parameter value and if the file exists in storage. Do not forget about tests. For more information please refer to https://github.com/artipie/rpm-adapter/issues/162:</body>
        <file>src/main/java/com/artipie/rpm/http/RpmUpload.java</file>
        <author>@olenagerasimova</author>
        <email>olena.gerasimova@gmail.com</email>
        <time>2020-06-11T12:38:42Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/257" closed="2020-06-17T18:18:48+00:00">257</issue>
    <ticket>226</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>226-ba71598e</id>
    <lines>34-37</lines>
    <body>Add one more (at least) test for this class to check that IllegalArgumentException is thrown if file is not found. After that replace `Rpm#meta` and `XmlMetaJoinITCase#meta` usages with this class usages. Check that the project has no more code to replace with this class usage.</body>
    <file>src/main/java/com/artipie/rpm/misc/FileInDir.java</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-11T06:03:21Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/259" closed="2020-06-19T05:38:42+00:00">259</issue>
    <ticket>213</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>213-52d0fd27</id>
    <lines>42-46</lines>
    <body>Add integration tests for RpmSlice to validate that it can answer requests coming from the rpm original client. There should be at least one test without authentication and one test with authentication, see https://stackoverflow.com/a/26852734/1723695 to configure the client side.</body>
    <file>src/main/java/com/artipie/rpm/http/RpmSlice.java</file>
    <author>Victor No&#xEB;l</author>
    <email>victor.noel@crazydwarves.org</email>
    <time>2020-06-07T08:50:02Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/273" closed="2020-06-23T09:00:38+00:00">273</issue>
        <ticket>259</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>259-71347a14</id>
        <lines>42-46</lines>
        <body>Add integration test for rpm repository: we need to verify that original rpm client (yum and dnf) can understand and work with rpm repository. Create rpm repo with our Rpm#batchUpdate first, then configure yum/dnf repository accordingly and list/install packages from this repository. To set authorisation see https://stackoverflow.com/a/26852734/1723695</body>
        <file>src/main/java/com/artipie/rpm/http/RpmSlice.java</file>
        <author>@olenagerasimova</author>
        <email>olena.gerasimova@gmail.com</email>
        <time>2020-06-17T08:52:07Z</time>
        <children>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/290" closed="2020-07-03T11:30:51+00:00">290</issue>
            <ticket>273</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>273-e9afba21</id>
            <lines>56-58</lines>
            <body>We need to test that dnf rpm client can interact with rpm repository created by rpm-adapter. Test can be the same as this one but use dnf instead of yum. Please introduce separate class for this test.</body>
            <file>src/test/java/com/artipie/rpm/http/RpmSliceYumITCase.java</file>
            <author>olenagerasimova</author>
            <email>olena.gerasimova@gmail.com</email>
            <time>2020-06-22T18:03:59Z</time>
            <children/>
          </puzzle>
        </children>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="true">
    <issue href="https://github.com/artipie/rpm-adapter/issues/268">268</issue>
    <ticket>110</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>110-69218d91</id>
    <lines>58-63</lines>
    <body>Meaningful error on broken package. Rpm should throw an exception when trying to add an invalid package. The type of exception must be IllegalArgumentException and its message "Reading of RPM package 'package' failed, data corrupt or malformed.", like described in showMeaningfulErrorWhenInvalidPackageSent. Implement it and then enable the test.</body>
    <file>src/test/java/com/artipie/rpm/RpmTest.java</file>
    <author>paulodamaso</author>
    <email>pauloeduardolobo@gmail.com</email>
    <time>2020-06-12T16:52:49Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/277" closed="2020-07-03T06:43:09+00:00">277</issue>
    <ticket>241</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>241-299104fc</id>
    <lines>48-50</lines>
    <body>Extend this test: add test methods to check `file()`, `maid()` and `tag()` methods of `PrimaryOutput` and add method to check generated primary.xml for libdeflt test rpm package.</body>
    <file>src/test/java/com/artipie/rpm/pkg/PrimaryOutputTest.java</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-18T11:55:42Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/278" closed="2020-06-25T10:48:37+00:00">278</issue>
    <ticket>241</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>241-a350bc6d</id>
    <lines>88-90</lines>
    <body>Introduce class from this method: the method is copied from FilePackage class, we need to extract class from it, test it and use it at least in FilePackage, ModifiableMetadataTest and here.</body>
    <file>src/test/java/com/artipie/rpm/pkg/PrimaryOutputTest.java</file>
    <author>olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-18T11:55:42Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/281" closed="2020-06-23T07:59:35+00:00">281</issue>
    <ticket>275</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>275-12a5bede</id>
    <lines>32-40</lines>
    <body>Repository options: create class to parse repo settings from yaml. Format: settings: --digest: sha256 --naming-policy: sha1 --filelists: true as described in https://github.com/artipie/artipie/issues/227. Consider extracting interface from CliParsedArguments, the interface may have two implementation: FromCliArguments and FromYaml. After that these settings should be passed to `RpmSlice` and `RpmUpload` to create `Rpm` instance accordingly to the settings.</body>
    <file>src/main/java/com/artipie/rpm/RpmOptions.java</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-19T11:03:34Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/286" closed="2020-06-23T11:00:11+00:00">286</issue>
        <ticket>281</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>281-4a7508e7</id>
        <lines>31-37</lines>
        <body>Create `Simple` implementation of `RepoConfig` which accepts digest, naming and filelists as constructor parameters, this implementation should also have empty constructor to create default configuration: (StandardNamingPolicy.PLAIN, Digest.SHA256, false). After that: 1) add `RepoConfig` as field to `Rpm` instead of 3 fields, do not change existing ctors, add new one and use `Simple` implementation 2) add `RepoConfig` to `RpmUpload` (and `RpmSlice`) to create `Rpm` instance with given configuration</body>
        <file>src/main/java/com/artipie/rpm/RepoConfig.java</file>
        <author>olenagerasimova</author>
        <email>olena.gerasimova@gmail.com</email>
        <time>2020-06-22T15:55:07Z</time>
        <children/>
      </puzzle>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/287" closed="2020-06-25T10:41:40+00:00">287</issue>
        <ticket>281</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>281-e86c51c6</id>
        <lines>62-70</lines>
        <body>Implement this class to read repository settings from yaml. Format: |settings: | digest: sha256 | naming-policy: sha1 | filelists: true as described in https://github.com/artipie/artipie/issues/227. For yaml parsing use eo-yaml (check example in artipie/artipie AuthFromYaml class) and accept `YamlMapping` instance into ctor (and probably keep it as field). Do not forget about test.</body>
        <file>src/main/java/com/artipie/rpm/RepoConfig.java</file>
        <author>olenagerasimova</author>
        <email>olena.gerasimova@gmail.com</email>
        <time>2020-06-22T15:55:07Z</time>
        <children/>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/282" closed="2020-07-03T09:21:43+00:00">282</issue>
    <ticket>275</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>275-eee2e5ba</id>
    <lines>41-42</lines>
    <body>Add unit test for this class to make sure it builds correct instance of {@link Option}.</body>
    <file>src/main/java/com/artipie/rpm/RpmOptions.java</file>
    <author>@olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-22T12:06:59Z</time>
    <children/>
  </puzzle>
  <puzzle alive="false">
    <issue href="https://github.com/artipie/rpm-adapter/issues/285" closed="2020-06-30T13:09:52+00:00">285</issue>
    <ticket>241</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>241-fffd0470</id>
    <lines>33-37</lines>
    <body>This matcher should also verify that `packages` attribute of metadata files has correct value of packages (the same as packages count). Add this check, correct mismatch description to say how many packages was found, what is `packages` attribute value and what is expected, do not forget about tests. After that use this matcher in `RpmTest`, `RpmITCase` and possibly in ModifiableMetadataTest and MetadataFileTest.</body>
    <file>src/test/java/com/artipie/rpm/hm/NodeHasPkgCount.java</file>
    <author>olenagerasimova</author>
    <email>olena.gerasimova@gmail.com</email>
    <time>2020-06-18T07:42:45Z</time>
    <children>
      <puzzle alive="false">
        <issue href="https://github.com/artipie/rpm-adapter/issues/307" closed="2020-07-02T09:20:50+00:00">307</issue>
        <ticket>285</ticket>
        <estimate>30</estimate>
        <role>DEV</role>
        <id>285-b9db6ed3</id>
        <lines>34-39</lines>
        <body>This matcher should also verify that `packages` attribute of metadata files has correct value of packages (the same as packages count). Add this check, correct mismatch description to say how many packages was found, what is `packages` attribute value and what is expected. The tests are already implemented, so enable them after implementing. After that use this matcher in `RpmTest`, `RpmITCase` and possibly in ModifiableMetadataTest and MetadataFileTest.</body>
        <file>src/test/java/com/artipie/rpm/hm/NodeHasPkgCount.java</file>
        <author>paulodamaso</author>
        <email>pauloeduardolobo@gmail.com</email>
        <time>2020-06-25T16:12:33Z</time>
        <children>
          <puzzle alive="true">
            <issue href="https://github.com/artipie/rpm-adapter/issues/310">310</issue>
            <ticket>307</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>307-d58d9aca</id>
            <lines>41-42</lines>
            <body>Test methods for description verification fail on windows: figure out why, fix it and remove disable annotation.</body>
            <file>src/test/java/com/artipie/rpm/hm/NodeHasPkgCountTest.java</file>
            <author>@olenagerasimova</author>
            <email>olena.gerasimova@gmail.com</email>
            <time>2020-06-30T18:39:50Z</time>
            <children/>
          </puzzle>
          <puzzle alive="false">
            <issue href="https://github.com/artipie/rpm-adapter/issues/311" closed="2020-07-03T13:29:26+00:00">311</issue>
            <ticket>307</ticket>
            <estimate>30</estimate>
            <role>DEV</role>
            <id>307-cda9f9c1</id>
            <lines>35-36</lines>
            <body>Use this matcher in `RpmTest` to validate that generated metadata files have correct packages amount.</body>
            <file>src/test/java/com/artipie/rpm/hm/NodeHasPkgCount.java</file>
            <author>@olenagerasimova</author>
            <email>olena.gerasimova@gmail.com</email>
            <time>2020-06-30T15:20:06Z</time>
            <children>
              <puzzle alive="false">
                <issue href="https://github.com/artipie/rpm-adapter/issues/316" closed="2020-09-10T13:44:24+00:00">316</issue>
                <ticket>311</ticket>
                <estimate>30</estimate>
                <role>DEV</role>
                <id>311-652b1692</id>
                <lines>44-45</lines>
                <body>Create proper unit test for this class (use metadata examples from test resources), do not forget to test mismatches descriptions.</body>
                <file>src/test/java/com/artipie/rpm/hm/StorageHasMetadata.java</file>
                <author>olenagerasimova</author>
                <email>olena.gerasimova@gmail.com</email>
                <time>2020-07-03T05:35:52Z</time>
                <children/>
              </puzzle>
              <puzzle alive="false">
                <issue href="https://github.com/artipie/rpm-adapter/issues/317" closed="2020-09-10T13:44:30+00:00">317</issue>
                <ticket>311</ticket>
                <estimate>30</estimate>
                <role>DEV</role>
                <id>311-7f1cb24b</id>
                <lines>46-49</lines>
                <body>Add one more check (here or create another matcher) for repomd.xml: we need to verify that exactly one repomd is present in storage and has info about metadatas, as example check RpmITCase#assertion(). Repomd should be verified at least in RpmTest and RpmITCase. @checkstyle ClassDataAbstractionCouplingCheck (500 lines)</body>
                <file>src/test/java/com/artipie/rpm/hm/StorageHasMetadata.java</file>
                <author>olenagerasimova</author>
                <email>olena.gerasimova@gmail.com</email>
                <time>2020-07-03T05:35:52Z</time>
                <children>
                  <puzzle alive="false">
                    <issue href="https://github.com/artipie/rpm-adapter/issues/359" closed="2020-10-27T07:50:18+00:00">359</issue>
                    <ticket>317</ticket>
                    <estimate>30</estimate>
                    <role>DEV</role>
                    <id>317-5a8b4b93</id>
                    <lines>33-36</lines>
                    <body>Implement StorageHasRepoMd matcher. StorageHasRepoMd should verify that repomd.xml has valid information about primary, filelists and other metadata files. After implementing this, enable tests in StorageHasRepoMdTest.</body>
                    <file>src/test/java/com/artipie/rpm/hm/StorageHasRepoMd.java</file>
                    <author>paulodamaso</author>
                    <email>pauloeduardolobo@gmail.com</email>
                    <time>2020-09-09T19:45:54Z</time>
                    <children/>
                  </puzzle>
                </children>
              </puzzle>
              <puzzle alive="true">
                <issue href="https://github.com/artipie/rpm-adapter/issues/360">360</issue>
                <ticket>311</ticket>
                <estimate>30</estimate>
                <role>DEV</role>
                <id>311-c333d3a1</id>
                <lines>47-49</lines>
                <body>Create proper unit test for this class (use metadata examples from test resources), do not forget to test mismatches descriptions. @checkstyle ClassDataAbstractionCouplingCheck (500 lines)</body>
                <file>src/test/java/com/artipie/rpm/hm/StorageHasMetadata.java</file>
                <author>@olenagerasimova</author>
                <email>olena.gerasimova@gmail.com</email>
                <time>2020-08-05T14:23:18Z</time>
                <children/>
              </puzzle>
            </children>
          </puzzle>
        </children>
      </puzzle>
    </children>
  </puzzle>
  <puzzle alive="true">
    <issue>unknown</issue>
    <ticket>376</ticket>
    <estimate>30</estimate>
    <role>DEV</role>
    <id>376-24e83852</id>
    <lines>78-80</lines>
    <body>Extract primary.xml `location` tag check from `writesSubdirsToLocation()` test method into separate matcher and add this matcher to `StorageHasMetadata` checks: we should always verify that `location` is specified correctly.</body>
    <file>src/test/java/com/artipie/rpm/RpmTest.java</file>
    <author>dependabot[bot]</author>
    <email>49699333+dependabot[bot]@users.noreply.github.com</email>
    <time>2021-04-14T06:21:35Z</time>
    <children/>
  </puzzle>
</puzzles>

/app/objects/safe_storage.rb:44:in `valid'
/app/objects/safe_storage.rb:37:in `save'
/app/objects/upgraded_storage.rb:47:in `save'
/app/objects/sync_storage.rb:35:in `block in save'
/app/objects/sync_storage.rb:35:in `synchronize'
/app/objects/sync_storage.rb:35:in `save'
/app/objects/puzzles.rb:46:in `save'
/app/objects/puzzles.rb:34:in `deploy'
/app/objects/job.rb:38:in `proceed'
/app/objects/job_starred.rb:33:in `proceed'
/app/objects/job_recorded.rb:32:in `proceed'
/app/objects/job_emailed.rb:35:in `proceed'
/app/objects/job_commiterrors.rb:36:in `proceed'
/app/objects/job_detached.rb:48:in `exclusive'
/app/objects/job_detached.rb:36:in `block in proceed'
/app/objects/job_detached.rb:36:in `fork'
/app/objects/job_detached.rb:36:in `proceed'
/app/0pdd.rb:357:in `block in <top (required)>'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1675:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1675:in `block in compile!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1013:in `block (3 levels) in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1032:in `route_eval'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1013:in `block (2 levels) in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1061:in `block in process_route'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1059:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1059:in `process_route'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1011:in `block in route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1008:in `each'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1008:in `route!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1129:in `block in dispatch!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `block in invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1124:in `dispatch!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:939:in `block in call!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `block in invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `catch'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1101:in `invoke'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:939:in `call!'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:929:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.1.0/lib/rack/protection/xss_header.rb:18:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.1.0/lib/rack/protection/path_traversal.rb:16:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.1.0/lib/rack/protection/json_csrf.rb:26:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.1.0/lib/rack/protection/base.rb:50:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.1.0/lib/rack/protection/base.rb:50:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.1.0/lib/rack/protection/frame_options.rb:31:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.3/lib/rack/logger.rb:17:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.3/lib/rack/common_logger.rb:38:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:253:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:246:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.3/lib/rack/head.rb:12:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.3/lib/rack/method_override.rb:24:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:216:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1991:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1542:in `block in call'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1769:in `synchronize'
/app/vendor/bundle/ruby/2.6.0/gems/sinatra-2.1.0/lib/sinatra/base.rb:1542:in `call'
/app/vendor/bundle/ruby/2.6.0/gems/rack-2.2.3/lib/rack/handler/webrick.rb:95:in `service'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/httpserver.rb:140:in `service'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/httpserver.rb:96:in `run'
/app/vendor/ruby-2.6.0/lib/ruby/2.6.0/webrick/server.rb:307:in `block in start_thread'

Please sign in to comment.