Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/artipie/rpm-adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
olenagerasimova committed Oct 28, 2021
2 parents 466843a + 2553e29 commit 855d156
Show file tree
Hide file tree
Showing 12 changed files with 338 additions and 31 deletions.
56 changes: 49 additions & 7 deletions src/main/java/com/artipie/rpm/meta/XmlEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
import com.artipie.rpm.pkg.Package;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.xml.stream.XMLEventFactory;
Expand Down Expand Up @@ -234,7 +237,8 @@ public void add(final XMLEventWriter writer, final Package.Meta meta) throws IOE
}

/**
* Builds `provides` tag.
* Builds `provides` tag. Attribute `flags` should be present if the version is present and
* in `provides` the only possible flag value is `EQ`.
* @param writer Xml event writer
* @param tags Tag info
* @throws XMLStreamException On error
Expand All @@ -244,18 +248,23 @@ private static void addProvides(final XMLEventWriter writer, final HeaderTags ta
final XMLEventFactory events = XMLEventFactory.newFactory();
writer.add(events.createStartElement(Primary.PRFX, Primary.NS_URL, "provides"));
final List<String> names = tags.providesNames();
final List<Optional<String>> flags = tags.providesFlags();
final List<HeaderTags.Version> versions = tags.providesVer();
for (int ind = 0; ind < names.size(); ind = ind + 1) {
writer.add(events.createStartElement(Primary.PRFX, Primary.NS_URL, "entry"));
writer.add(events.createAttribute("name", names.get(ind)));
Primary.addEntryAttr(writer, events, versions, ind);
Primary.addEntryAttr(
writer, events, versions, ind, flags, HeaderTags.Flags.EQUAL.notation()
);
writer.add(events.createEndElement(Primary.PRFX, Primary.NS_URL, "entry"));
}
writer.add(events.createEndElement(Primary.PRFX, Primary.NS_URL, "provides"));
}

/**
* Builds `requires` tag.
* Builds `requires` tag. Items with names started on `rpmlib(` or `config(` are excluded,
* duplicates without version are also excluded.
* About `flags` attribute check {@link Primary#findFlag(List, Map, String)}.
* @param writer Xml event writer
* @param tags Tag info
* @throws XMLStreamException On error
Expand All @@ -265,13 +274,27 @@ private static void addRequires(final XMLEventWriter writer, final HeaderTags ta
final XMLEventFactory events = XMLEventFactory.newFactory();
writer.add(events.createStartElement(Primary.PRFX, Primary.NS_URL, "requires"));
final List<String> names = tags.requires();
final List<Optional<String>> flags = tags.requireFlags();
final List<HeaderTags.Version> versions = tags.requiresVer();
final Map<String, Integer> items = new HashMap<>(names.size());
final Set<String> duplicates = new HashSet<>(names.size());
for (int ind = 0; ind < names.size(); ind = ind + 1) {
if (!names.get(ind).startsWith("rpmlib(")) {
final String name = names.get(ind);
if (!name.startsWith("rpmlib(")
&& !name.startsWith("config(") && !duplicates.contains(name)) {
writer.add(events.createStartElement(Primary.PRFX, Primary.NS_URL, "entry"));
writer.add(events.createAttribute("name", names.get(ind)));
Primary.addEntryAttr(writer, events, versions, ind);
writer.add(events.createAttribute("name", name));
final String item = String.join(
"", name, versions.get(ind).toString()
);
Primary.addEntryAttr(
writer, events, versions, ind, flags, Primary.findFlag(flags, items, item)
);
items.put(item, ind);
writer.add(events.createEndElement(Primary.PRFX, Primary.NS_URL, "entry"));
if (versions.get(ind).ver().isEmpty()) {
duplicates.add(name);
}
}
}
writer.add(events.createEndElement(Primary.PRFX, Primary.NS_URL, "requires"));
Expand Down Expand Up @@ -346,18 +369,37 @@ private static void addAttributes(final XMLEventWriter writer, final String tag,
* @param events Xml events
* @param versions Versions
* @param ind Current index
* @param flags Entries flags
* @param def Default flag
* @throws XMLStreamException On error
* @checkstyle ParameterNumberCheck (5 lines)
*/
private static void addEntryAttr(final XMLEventWriter writer, final XMLEventFactory events,
final List<HeaderTags.Version> versions, final int ind) throws XMLStreamException {
final List<HeaderTags.Version> versions, final int ind,
final List<Optional<String>> flags, final String def)
throws XMLStreamException {
if (ind < versions.size() && !versions.get(ind).ver().isEmpty()) {
writer.add(events.createAttribute("ver", versions.get(ind).ver()));
writer.add(events.createAttribute("epoch", versions.get(ind).epoch()));
versions.get(ind).rel().ifPresent(
new UncheckedConsumer<>(rel -> writer.add(events.createAttribute("rel", rel)))
);
writer.add(events.createAttribute("flags", flags.get(ind).orElse(def)));
}
}

/**
* Try to find flag for `requires` entry: if there en entry with such name and version,
* use the flag it has. If there is no such entry, write `EQ`.
* @param flags Flags list
* @param items Items: names and versions
* @param item Current name and version
* @return Flag value
*/
private static String findFlag(final List<Optional<String>> flags,
final Map<String, Integer> items, final String item) {
return Optional.ofNullable(items.get(item)).flatMap(flags::get)
.orElse(HeaderTags.Flags.EQUAL.notation());
}
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/artipie/rpm/pkg/HeaderTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,11 @@ public String epoch() {
return this.part("epoch").orElse("0");
}

@Override
public String toString() {
return this.val;
}

/**
* Get version part by name.
* @param name Part group name, see {@link Version#PTRN}
Expand Down
91 changes: 79 additions & 12 deletions src/test/java/com/artipie/rpm/asto/AstoMetadataAddTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@
import com.artipie.asto.Storage;
import com.artipie.asto.blocking.BlockingStorage;
import com.artipie.asto.memory.InMemoryStorage;
import com.artipie.asto.test.TestResource;
import com.artipie.rpm.Digest;
import com.artipie.rpm.RepoConfig;
import com.artipie.rpm.StandardNamingPolicy;
import com.artipie.rpm.TestRpm;
import com.artipie.rpm.hm.IsXmlEqual;
import com.artipie.rpm.meta.XmlPackage;
import com.artipie.rpm.pkg.FilePackage;
import com.artipie.rpm.pkg.FilePackageHeader;
import com.artipie.rpm.pkg.Package;
import com.jcabi.matchers.XhtmlMatchers;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.zip.GZIPInputStream;
import org.cactoos.list.ListOf;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -30,28 +37,30 @@
* @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
* @checkstyle MagicNumberCheck (500 lines)
*/
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
class AstoMetadataAddTest {

/**
* Test storage.
* Digest fot test.
*/
private Storage storage;
private static final Digest DGST = Digest.SHA256;

/**
* Test config.
* Test storage.
*/
private RepoConfig conf;
private Storage storage;

@BeforeEach
void init() {
this.storage = new InMemoryStorage();
this.conf = new RepoConfig.Simple(Digest.SHA256, StandardNamingPolicy.SHA256, false);
}

@Test
void addsEmptyFiles() throws IOException {
final Key temp = new AstoMetadataAdd(this.storage, this.conf)
.perform(Collections.emptyList()).toCompletableFuture().join();
final Key temp = new AstoMetadataAdd(
this.storage,
new RepoConfig.Simple(AstoMetadataAddTest.DGST, StandardNamingPolicy.SHA256, false)
).perform(Collections.emptyList()).toCompletableFuture().join();
MatcherAssert.assertThat(
"Failed to generate 4 items: metadatas and checksums",
this.storage.list(Key.ROOT).join(),
Expand All @@ -63,20 +72,66 @@ void addsEmptyFiles() throws IOException {
this.readAndUnpack(new Key.From(temp, XmlPackage.PRIMARY.name())),
StandardCharsets.UTF_8
),
XhtmlMatchers.hasXPaths(
"/*[local-name()='metadata' and @packages='0']"
)
XhtmlMatchers.hasXPaths("/*[local-name()='metadata' and @packages='0']")
);
MatcherAssert.assertThat(
"Failed to generate empty other xml",
new String(
this.readAndUnpack(new Key.From(temp, XmlPackage.OTHER.name())),
StandardCharsets.UTF_8
),
XhtmlMatchers.hasXPaths(
"/*[local-name()='otherdata' and @packages='0']"
XhtmlMatchers.hasXPaths("/*[local-name()='otherdata' and @packages='0']")
);
}

@Test
void addsPackagesMetadata() throws IOException {
new TestResource("AstoMetadataAddTest/primary.xml.gz")
.saveTo(this.storage, new Key.From("metadata", "primary.xml.gz"));
new TestResource("AstoMetadataAddTest/other.xml.gz")
.saveTo(this.storage, new Key.From("metadata", "other.xml.gz"));
new TestResource("AstoMetadataAddTest/filelists.xml.gz")
.saveTo(this.storage, new Key.From("metadata", "filelists.xml.gz"));
final TestRpm.Libdeflt libdeflt = new TestRpm.Libdeflt();
final TestRpm.Abc abc = new TestRpm.Abc();
final Key temp = new AstoMetadataAdd(
this.storage,
new RepoConfig.Simple(AstoMetadataAddTest.DGST, StandardNamingPolicy.SHA256, true)
).perform(
new ListOf<Package.Meta>(
new FilePackage.Headers(
new FilePackageHeader(libdeflt.path()).header(),
libdeflt.path(), Digest.SHA256, libdeflt.path().getFileName().toString()
),
new FilePackage.Headers(
new FilePackageHeader(abc.path()).header(),
abc.path(), Digest.SHA256, abc.path().getFileName().toString()
)
)
).toCompletableFuture().join();
MatcherAssert.assertThat(
"Failed to generate 6 items: metadatas and checksums",
this.storage.list(temp).join(),
Matchers.iterableWithSize(6)
);
MatcherAssert.assertThat(
"Failed to generate correct primary xml",
new TestResource("AstoMetadataAddTest/primary-res.xml").asPath(),
new IsXmlEqual(this.readAndUnpack(new Key.From(temp, XmlPackage.PRIMARY.name())))
);
MatcherAssert.assertThat(
"Failed to generate correct other xml",
new TestResource("AstoMetadataAddTest/other-res.xml").asPath(),
new IsXmlEqual(this.readAndUnpack(new Key.From(temp, XmlPackage.OTHER.name())))
);
MatcherAssert.assertThat(
"Failed to generate correct filelists xml",
new TestResource("AstoMetadataAddTest/filelists-res.xml").asPath(),
new IsXmlEqual(this.readAndUnpack(new Key.From(temp, XmlPackage.FILELISTS.name())))
);
this.checksumCheck(temp, XmlPackage.PRIMARY);
this.checksumCheck(temp, XmlPackage.OTHER);
this.checksumCheck(temp, XmlPackage.FILELISTS);
}

private byte[] readAndUnpack(final Key key) throws IOException {
Expand All @@ -87,4 +142,16 @@ private byte[] readAndUnpack(final Key key) throws IOException {
);
}

private void checksumCheck(final Key res, final XmlPackage other) {
MatcherAssert.assertThat(
String.format("Checksum and size are expected to be stored for %s", other.name()),
new String(
new BlockingStorage(this.storage)
.value(new Key.From(res, other.name(), AstoMetadataAddTest.DGST.name())),
StandardCharsets.UTF_8
),
Matchers.matchesPattern("[0-9a-z]* \\d+")
);
}

}
4 changes: 1 addition & 3 deletions src/test/java/com/artipie/rpm/meta/XmlEventPrimaryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ void writesPackageInfo(final String rpm, final String res) throws XMLStreamExcep
.ignoreElementContentWhitespace()
.normalizeWhitespace()
.withNodeFilter(node -> !"file".equals(node.getLocalName()))
.withAttributeFilter(
attr -> !"flags".equals(attr.getName()) && !"pre".equals(attr.getName())
)
.withAttributeFilter(attr -> !"pre".equals(attr.getName()))
);
}

Expand Down
25 changes: 25 additions & 0 deletions src/test/resources-binary/AstoMetadataAddTest/filelists-res.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<filelists xmlns="http://linux.duke.edu/metadata/filelists" packages="3">

<package pkgid="ce6f64001104e098d5e799d6a10e7cfeadf2320b8955c86e3f8d15872d1544fd" name="mesa-libxatracker" arch="i686">
<version epoch="0" ver="18.3.4" rel="10.el7"/>
<file>/usr/lib/libxatracker.so.2</file>
<file>/usr/lib/libxatracker.so.2.4.0</file>
</package>
<package pkgid="47bbb8b2401e8853812e6340f4197252b92463c132f64a257e18c0c8c83ae462" name="libdeflt1_0" arch="armv7hl">
<version epoch="0" ver="2020.03.27" rel="25.1"/>
<file>/usr/lib/libdeflt.so.1.0</file>
<file type="dir">/usr/share/licenses/libdeflt1_0</file>
<file>/usr/share/licenses/libdeflt1_0/CDDL.Schily.txt</file>
</package>
<package pkgid="b9d10ae3485a5c5f71f0afb1eaf682bfbea4ea667cc3c3975057d6e3d8f2e905" name="abc" arch="ppc64le">
<version epoch="0" ver="1.01" rel="26.git20200127.fc32"/>
<file>/usr/bin/abc</file>
<file type="dir">/usr/lib/.build-id/cb</file>
<file>/usr/lib/.build-id/cb/263ca8bdb2d581b1a12e604c0e30635e69c889</file>
<file type="dir">/usr/share/doc/abc</file>
<file>/usr/share/doc/abc/README.md</file>
<file>/usr/share/doc/abc/readmeaig</file>
<file>/usr/share/man/man1/abc.1.gz</file>
</package>
</filelists>
Binary file not shown.
22 changes: 22 additions & 0 deletions src/test/resources-binary/AstoMetadataAddTest/other-res.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<otherdata xmlns="http://linux.duke.edu/metadata/other" packages="3">
<package pkgid="ce6f64001104e098d5e799d6a10e7cfeadf2320b8955c86e3f8d15872d1544fd" name="mesa-libxatracker" arch="i686">
<version epoch="0" ver="18.3.4" rel="10.el7"/>
<changelog author="Dave Airlie &lt;airlied@redhat.com&gt; - 18.3.4-1" date="1550577600">- mesa 18.3.4</changelog>
<changelog author="Dave Airlie &lt;airlied@redhat.com&gt; - 18.3.4-2" date="1551441600">- add shm fix</changelog>
<changelog author="Dave Airlie &lt;airlied@redhat.com&gt; - 18.3.4-3" date="1553601600">- fix remote shm</changelog>
<changelog author="Dave Airlie &lt;airlied@redhat.com&gt; - 18.3.4-4" date="1553688000">- Enable i686 vulkan drivers for 32-bit apps</changelog>
<changelog author="Dave Airlie &lt;airlied@redhat.com&gt; - 18.3.4-5" date="1554379200">- fix remote shm patch</changelog>
<changelog author="Ben Crocker &lt;bcrocker@redhat.com&gt; - 18.3.4-6" date="1578312000">- Patch to require Large CodeModel for llvmpipe on ppc64/ppc64le (#1543572)</changelog>
<changelog author="Tomas Pelka &lt;tpelka@redhat.com&gt; - 18.3.4-7" date="1579780800">- bump version and rebuild to avoind conflict with 7.7.z build (#1543572)</changelog>
<changelog author="Dave Airlie &lt;airlied@redhat.com&gt; - 18.3.4-8" date="1584100800">- Backport put/get shm fixes to EL7 (#1749699)</changelog>
<changelog author="Adam Jackson &lt;ajax@redhat.com&gt; - 18.3.4-9" date="1587384000">- Fix context sharing with multiple screens for i965</changelog>
<changelog author="Adam Jackson &lt;ajax@redhat.com&gt; - 18.3.4-10" date="1592481600">- Revert the previous fix due to regressions in Firefox, Chrome, etc.</changelog>
</package>
<package pkgid="47bbb8b2401e8853812e6340f4197252b92463c132f64a257e18c0c8c83ae462" name="libdeflt1_0" arch="armv7hl">
<version epoch="0" ver="2020.03.27" rel="25.1"/>
</package>
<package pkgid="b9d10ae3485a5c5f71f0afb1eaf682bfbea4ea667cc3c3975057d6e3d8f2e905" name="abc" arch="ppc64le">
<version epoch="0" ver="1.01" rel="26.git20200127.fc32"/>
</package>
</otherdata>
Binary file not shown.
Loading

0 comments on commit 855d156

Please sign in to comment.