Skip to content

Commit

Permalink
Added the ability to add information programmatically into the build …
Browse files Browse the repository at this point in the history
…info page using the `BuildInfo` class.

You can use this class like this:
```
    @BeforeAll
    public static void recordToggles() {
        BuildInfo.section("Toggles").setProperty("toggle1", "on");
        BuildInfo.section("Toggles").setProperty("toggle2", "on");

        BuildInfo.section("Microservice Versions").setProperty("service 1", "1.2.3");
        BuildInfo.section("Microservice Versions").setProperty("service 2", "1.2.4");
    }
```
These values will now appear in the Info page.
  • Loading branch information
wakaleo committed Sep 15, 2023
1 parent 5ec7666 commit ecdbd79
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 1 deletion.
6 changes: 5 additions & 1 deletion serenity-model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@
<version>${jsoup.version}</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package net.serenitybdd.model.buildinfo;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.cucumber.core.internal.com.fasterxml.jackson.databind.ObjectMapper;
import net.serenitybdd.model.di.ModelInfrastructure;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class BuildInfo {

private static Map<String, BuildInfoSection> buildInfoSections = new ConcurrentHashMap<>();

private static final Logger LOGGER = LoggerFactory.getLogger(BuildInfo.class);

private static final ObjectMapper objectMapper = new ObjectMapper();

public static BuildInfoSection section(String sectionName) {
BuildInfo.load();
return buildInfoSections.computeIfAbsent(sectionName, name -> new BuildInfoSection(name));
}

static void save() {
File reportDir = ModelInfrastructure.getConfiguration().getOutputDirectory();
// Check if the report directory exists, if not create it
if (!reportDir.exists()) {
reportDir.mkdirs();
}

File file = new File(reportDir, "buildInfo.json");
try {
objectMapper.writeValue(file, buildInfoSections);
} catch (IOException e) {
LOGGER.warn("Unable to save build info", e);
}
}

public static void clear() {
buildInfoSections.clear();
}

public static void load() {
File reportDir = ModelInfrastructure.getConfiguration().getOutputDirectory();
File file = new File(reportDir, "buildInfo.json");
if (file.exists()) {
try {
Map<String, BuildInfoSection> loadedSections = objectMapper.readValue(file, objectMapper.getTypeFactory().constructMapType(Map.class, String.class, BuildInfoSection.class));
buildInfoSections.putAll(loadedSections);
} catch (IOException e) {
LOGGER.warn("Unable to load build info", e);
}
}
}

public static List<String> getSections() {
return buildInfoSections.keySet().stream().sorted().collect(Collectors.toList());
}

public static Map<String, String> getSection(String sectionName) {
return buildInfoSections.getOrDefault(sectionName, new BuildInfoSection(sectionName)).getValues();
}

public static class BuildInfoSection {
private String sectionName;
private Map<String, String> values = new HashMap<>();

// No-args constructor for Jackson
public BuildInfoSection() {
}

public BuildInfoSection(String sectionName) {
this.sectionName = sectionName;
}

@JsonProperty("sectionName")
public String getSectionName() {
return sectionName;
}

public void setSectionName(String sectionName) {
this.sectionName = sectionName;
}

@JsonProperty("values")
public Map<String, String> getValues() {
return values;
}

public void setValues(Map<String, String> values) {
this.values = values;
}

public void setProperty(String property, String value) {
values.put(property, value);
BuildInfo.save();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ public BuildProperties getBuildProperties() {
driverCapabilityRecord.getDriverCapabilities().get(driver).toString())
);

//
// Programmatically-added build info
//
BuildInfo.load();
BuildInfo.getSections().forEach(
section -> sections.put(section, BuildInfo.getSection(section))
);

addCustomPropertiesTo(generalProperties);

Map<String, Properties> driverPropertiesMap = driverCapabilityRecord.getDriverCapabilities();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package net.serenitybdd.model.buildinfo;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class WhenStoringBuildInformationProgrammatically {
@Test
void we_can_add_arbitrary_build_info_fields_programmatically() {

// Given
BuildInfo.section("Toggles").setProperty("toggle1", "on");

// When
BuildInfo.clear();
BuildInfo.load();

// Then
assertThat(BuildInfo.section("Toggles").getValues()).containsEntry("toggle1", "on");
}

@Test
void we_can_several_values_in_each_section() {

// Given
BuildInfo.section("Toggles").setProperty("toggle1", "on");
BuildInfo.section("Toggles").setProperty("toggle2", "on");
BuildInfo.section("Toggles").setProperty("toggle3", "off");

// When
BuildInfo.clear();
BuildInfo.load();

// Then
assertThat(BuildInfo.section("Toggles").getValues()).containsEntry("toggle1", "on");
assertThat(BuildInfo.section("Toggles").getValues()).containsEntry("toggle2", "on");
assertThat(BuildInfo.section("Toggles").getValues()).containsEntry("toggle3", "off");
}

@Test
void we_can_several_different_sections() {

// Given
BuildInfo.section("Toggles").setProperty("toggle1", "on");
BuildInfo.section("Toggles").setProperty("toggle2", "on");

BuildInfo.section("Versions").setProperty("module1", "1.2.3");
BuildInfo.section("Versions").setProperty("module2", "2.3.4");

// When
BuildInfo.clear();
BuildInfo.load();

// Then
assertThat(BuildInfo.section("Toggles").getValues()).containsEntry("toggle1", "on");
assertThat(BuildInfo.section("Toggles").getValues()).containsEntry("toggle2", "on");
assertThat(BuildInfo.section("Versions").getValues()).containsEntry("module1", "1.2.3");
assertThat(BuildInfo.section("Versions").getValues()).containsEntry("module2", "2.3.4");
}
}

0 comments on commit ecdbd79

Please sign in to comment.