Skip to content

Commit

Permalink
Add integration tests for reproducible timestamps in archives
Browse files Browse the repository at this point in the history
  • Loading branch information
Zlika committed Dec 21, 2024
1 parent 1d42636 commit 3e00310
Show file tree
Hide file tree
Showing 20 changed files with 377 additions and 1 deletion.
93 changes: 93 additions & 0 deletions tycho-its/projects/reproducible-archive-timestamps/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>reproducible.archive.timestamps</groupId>
<artifactId>reproducible.archive.timestamps.parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>

<modules>
<module>reproducible.bundle</module>
<module>reproducible.bundle.feature</module>
<module>reproducible.iu</module>
<module>reproducible.repository</module>
</modules>

<properties>
<project.build.outputTimestamp>2023-01-01T00:00:00Z</project.build.outputTimestamp>
<target-platform>http://download.eclipse.org/releases/latest</target-platform>
</properties>

<repositories>
<repository>
<id>repo</id>
<layout>p2</layout>
<url>${target-platform}</url>
</repository>
</repositories>

<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>

<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<environments>
<environment>
<os>linux</os>
<ws>gtk</ws>
<arch>x86</arch>
</environment>
</environments>
</configuration>
</plugin>

<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-packaging-plugin</artifactId>
<version>${tycho-version}</version>
</plugin>

<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<goals>
<goal>plugin-source</goal>
<goal>feature-source</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>attach-p2-metadata</id>
<phase>package</phase>
<goals>
<goal>p2-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin.includes = feature.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<feature
id="reproducible.bundle.feature"
label="Feature"
version="1.0.0">

<plugin
id="reproducible.bundle"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>

</feature>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>reproducible.archive.timestamps</groupId>
<artifactId>reproducible.archive.timestamps.parent</artifactId>
<version>1.0.0</version>
</parent>

<artifactId>reproducible.bundle.feature</artifactId>
<packaging>eclipse-feature</packaging>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Reproducible-bundle
Bundle-SymbolicName: reproducible.bundle
Bundle-Version: 1.0.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Reproducible-bundle
Bundle-SymbolicName: reproducible.bundle.attached
Bundle-Version: 1.0.0
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>reproducible.archive.timestamps</groupId>
<artifactId>reproducible.archive.timestamps.parent</artifactId>
<version>1.0.0</version>
</parent>

<artifactId>reproducible.bundle</artifactId>
<packaging>eclipse-plugin</packaging>

<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-custom-bundle-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>attached</id>
<phase>package</phase>
<goals>
<goal>custom-bundle</goal>
</goals>
<configuration>
<bundleLocation>${project.basedir}/custom</bundleLocation>
<classifier>attached</classifier>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<includes>
<include>**/*.class</include>
</includes>
</fileSet>
</fileSets>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package reproducible.bundle;

public class PublicClass
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version='1.0' encoding='UTF-8'?>
<unit id='reproducible.iu' version='1.0.0' singleton='false'>
<update id='reproducible.iu' range='[0.0.0,1.0.0)' severity='0'/>
<properties>
<property name='org.eclipse.equinox.p2.name' value='Root files for my product'/>
</properties>
<touchpoint id='org.eclipse.equinox.p2.native' version='1.0.0'/>
<touchpointData>
<instructions>
<instruction key='install'>
unzip(source:@artifact, target:${installFolder});
</instruction>
<instruction key='uninstall'>
cleanupzip(source:@artifact, target:${installFolder});
</instruction>
</instructions>
</touchpointData>
</unit>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>reproducible.archive.timestamps</groupId>
<artifactId>reproducible.archive.timestamps.parent</artifactId>
<version>1.0.0</version>
</parent>

<artifactId>reproducible.iu</artifactId>
<packaging>p2-installable-unit</packaging>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
requires.0.namespace=org.eclipse.equinox.p2.iu
requires.0.name=reproducible.iu
requires.0.range=[$version$,$version$]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<?pde version="3.5"?>

<product name="Main Product" uid="main.product.id" id="product.branding" application="product.bundle.application" version="1.0.0" useFeatures="false" includeLaunchers="false">

<configIni use="default">
</configIni>

<launcherArgs>
</launcherArgs>

<plugins>
<plugin id="org.eclipse.core.runtime"/>
</plugins>


</product>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>reproducible.archive.timestamps</groupId>
<artifactId>reproducible.archive.timestamps.parent</artifactId>
<version>1.0.0</version>
</parent>

<artifactId>reproducible.repository</artifactId>
<packaging>eclipse-repository</packaging>

<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-repository-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>assemble-maven-repository</id>
<phase>verify</phase>
<goals>
<goal>assemble-maven-repository</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>materialize-products</id>
<goals>
<goal>materialize-products</goal>
</goals>
</execution>
<execution>
<id>archive-products</id>
<goals>
<goal>archive-products</goal>
</goals>
</execution>
</executions>
<configuration>
<formats>
<linux>zip</linux>
<mac>zip</mac>
<windows>zip</windows>
</formats>
</configuration>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*******************************************************************************
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tycho.test.reproducible;

import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.maven.it.Verifier;
import org.eclipse.tycho.test.AbstractTychoIntegrationTest;
import org.junit.Assert;
import org.junit.Test;

public class ReproducibleArchiveTimestampsTest extends AbstractTychoIntegrationTest {
// The ZipEntry.getLastModifiedTime() method uses the default timezone to
// convert date and time fields to Instant, so we also use the default timezone
// for the expected timestamp here.
private static final String EXPECTED_TIMESTAMP_STRING = "2023-01-01T00:00:00";
private static final Instant EXPECTED_TIMESTAMP_INSTANT = LocalDateTime.parse(EXPECTED_TIMESTAMP_STRING)
.toInstant(OffsetDateTime.now().getOffset());

/**
* Check that the timestamp of the files inside the produced archives is equal
* to the one specified in the "project.build.outputTimestamp" property of the
* pom file.
*/
@Test
public void test() throws Exception {
Verifier verifier = getVerifier("reproducible-archive-timestamps");
verifier.executeGoals(List.of("clean", "verify"));
verifier.verifyErrorFreeLog();

// Check timestamps of files in archives
checkTimestamps(verifier.getBasedir() + "/reproducible.bundle/target/reproducible.bundle-1.0.0.jar");
checkTimestamps(verifier.getBasedir() + "/reproducible.bundle/target/reproducible.bundle-1.0.0-attached.jar");
checkTimestamps(verifier.getBasedir() + "/reproducible.bundle/target/reproducible.bundle-1.0.0-sources.jar");
checkTimestamps(
verifier.getBasedir() + "/reproducible.bundle.feature/target/reproducible.bundle.feature-1.0.0.jar");
checkTimestamps(verifier.getBasedir()
+ "/reproducible.bundle.feature/target/reproducible.bundle.feature-1.0.0-sources-feature.jar");
checkTimestamps(verifier.getBasedir() + "/reproducible.iu/target/reproducible.iu-1.0.0.zip");
checkTimestamps(verifier.getBasedir() + "/reproducible.repository/target/reproducible.repository-1.0.0.zip");
checkTimestamps(verifier.getBasedir() + "/reproducible.repository/target/p2-site.zip");
}

private void checkTimestamps(String file) throws IOException {
try (ZipFile zip = new ZipFile(file)) {
final var entries = zip.entries();
while (entries.hasMoreElements()) {
final ZipEntry entry = entries.nextElement();
Assert.assertEquals(EXPECTED_TIMESTAMP_INSTANT, entry.getLastModifiedTime().toInstant());
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@ private void createCommonsCompressTarGz(File productArchive, File sourceDir) thr
TarGzArchiver archiver = new TarGzArchiver();
archiver.setStoreCreationTimeAttribute(storeCreationTime);
archiver.setLog(getLog());
// configure for Reproducible Builds based on outputTimestamp value
MavenArchiver.parseBuildOutputTimestamp(outputTimestamp).map(FileTime::from)
.ifPresent(modifiedTime -> archiver.configureReproducibleBuild(modifiedTime));
archiver.addDirectory(sourceDir);
archiver.setDestFile(productArchive);
archiver.createArchive();
Expand Down
Loading

0 comments on commit 3e00310

Please sign in to comment.