Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions swatch-tally/ct/java/tests/BaseTallyComponentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public class BaseTallyComponentTest {
// --- Instance fields ---

protected final TallyDbHostSeeder seeder = new TallyDbHostSeeder(swatchDatabase);

protected String orgId;
protected RbacAccessTestHelper rbacHelper;

Expand Down
252 changes: 182 additions & 70 deletions swatch-tally/ct/java/tests/TallyNightlyHbiTest.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,21 @@
import static utils.TallyTestProducts.RHEL_FOR_X86;

import com.redhat.swatch.component.tests.api.TestPlanName;
import com.redhat.swatch.component.tests.api.hbi.HbiDbConnector;
import com.redhat.swatch.component.tests.api.hbi.HostConnector.SeededHost;
import com.redhat.swatch.component.tests.api.hbi.HostStateManager;
import com.redhat.swatch.component.tests.logging.Log;
import com.redhat.swatch.tally.test.model.InstanceData;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import utils.TallyHbiDbSeeder;
import utils.TallyHbiDbSeeder.SeededHost;

/**
* Component tests for RHEL physical host tally with socket increase mapping.
Expand All @@ -50,30 +52,35 @@
*
* <p>Matches IQE test: test_validate_tally_on_physical_rhel_sockets
*/
public class TallyRhelTest extends BaseTallyComponentTest {
public class TallyNightlyTest extends BaseTallyComponentTest {

private TallyHbiDbSeeder hbiSeeder;
private HostStateManager hostManager;

/**
* Socket increase mapping for RHEL physical hosts. Maps actual socket count -> reported socket
* count for tally.
*/
private static final Map<Integer, Integer> RHEL_PER_SOCKET_INCREASE =
Map.of(1, 2, 2, 2, 4, 4, 7, 8);

/**
* Provider for socket increase mapping test parameters. Matches
* IQE's @pytest.mark.parametrize("sockets", rhel_per_socket_increase.keys())
*/
static Stream<Arguments> socketMappingProvider() {
return TallyHbiDbSeeder.getRhelPerSocketIncreaseMap().entrySet().stream()
return RHEL_PER_SOCKET_INCREASE.entrySet().stream()
.map(entry -> Arguments.of(entry.getKey(), entry.getValue()));
}

@BeforeEach
void setupHbiSeeder() {
// Initialize HBI seeder with database service (auto-configured for local/OpenShift)
hbiSeeder = new TallyHbiDbSeeder(hbiDatabase);
void setupHostManager() {
hostManager = new HostStateManager(new HbiDbConnector(hbiDatabase));
}

@AfterEach
void cleanupHbiHosts() {
// Rollback: delete all HBI hosts inserted during test
if (hbiSeeder != null) {
hbiSeeder.deleteAllInsertedHosts();
void cleanupHosts() {
if (hostManager != null) {
hostManager.cleanupAll();
}
}

Expand All @@ -88,14 +95,11 @@ void cleanupHbiHosts() {
* correct display_name, category, and labeled_measurements
*/
@TestPlanName("nightly-tally-TC001")
@ParameterizedTest(name = "Physical RHEL: {0} actual sockets -> {1} reported sockets")
@ParameterizedTest(name = "Physical RHEL: {0} starting sockets -> {1} reported sockets")
@MethodSource("socketMappingProvider")
void test_validate_tally_on_physical_rhel_sockets(
int actualSockets, int expectedReportedSockets) {
String inventoryId = helpers.generateUUIDOfSize(false, 5) + "-" + actualSockets;
String subscriptionManagerId = helpers.generateUUIDOfSize(false, 5) + "-" + actualSockets;
String displayName =
"RHEL Host " + helpers.generateUUIDOfSize(false, 5) + actualSockets + " sockets";
int startingSockets, int expectedReportedSockets) {

// Given: Org is opted in
service.createOptInConfig(orgId);

Expand All @@ -110,19 +114,20 @@ void test_validate_tally_on_physical_rhel_sockets(
Log.info("Initial sockets: %.0f", initialSockets);

// And: Create RHEL host
int cores = actualSockets; // 1 core per socket (matches IQE)
int cores = startingSockets; // 1 core per socket (matches IQE)
String displayName = String.format("RHEL-Physical-%dsockets-%dcores", startingSockets, cores);

SeededHost host =
hbiSeeder
.rhelHost(orgId)
.inventoryId("inventory-" + actualSockets)
.subscriptionManagerId("subman-" + actualSockets)
hostManager
.createRhsmHost(orgId)
.displayName(displayName)
.rhsmFact("RH_PROD", List.of("69"))
.rhsmFact("ARCHITECTURE", "x86_64")
.cores(cores)
.sockets(actualSockets)
.sockets(startingSockets)
.insert();
Comment on lines +121 to 128

@mstead mstead Aug 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd prefer that when setting facts, we didn't use raw key/value pairs. Instead, each type of fact set should define the facts that are applicable and the builder pattern is used to define them.

A HostBuilder should always define a Host and I'm not sure that we need the RhsmHost/QpcHost implementations of these classes since they are really 'reporters' and we are building an HBI host.

Here the HostManager creates a HostBuilder (Host) that allows setting the applicable RHSM facts (rhsm-conduit reporter) using an RhsmFacts builder pattern which allows facts to be defined in a single place and allows the facts to be discoverable via the class.

    SeededHost host = hostManager
            // Initializes a HostBuilder for the new Host.
            .createHost(orgId) 
            // Allow setting common HBI properties for the host 
            .displayName("Multi-Reporter-Host")
            // Defines the RHSM facts that were reported for this HBI host.
            // The setter should also ensure that 'rhsm-conduit' is added as a reporter
            // which is stored via the Host held by the HostBuilder. 
            .rhsmFacts(
                RhsmFacts.builder()
                    // Set the default facts
                    .defaultFacts()
                    // Override any defaults
                    .products(List.of("69"))
                    .architecture("x86_64")
                    // builds and returns the RhsmFacts object. This object could define a toMap() that
                    // encapsulates the key/value usage for a connector.
                    .build()
            )
            // Cores/sockets do not exist at the root of the host and are facts that get reported
            // as part of the system profile (normalized into cores/sockets on ingestion).
            // We could follow suit here and use a builder patter those as well.
            .setSystemProfileFacts(
                 SystemProfileFacts.builder()
                    .coresPerSocket(2)
                    .numberOfSockets(2)
                    .build()
             )
            .insert();


Log.info("Inserted host %s: %d cores, %d sockets", host.hostId(), cores, actualSockets);
Log.info("Inserted host %s: %d cores, %d sockets", host.hostId(), cores, startingSockets);

// And: Run tally
service.tallyOrg(orgId);
Expand Down Expand Up @@ -169,6 +174,6 @@ void test_validate_tally_on_physical_rhel_sockets(
instance.getMeasurements().get(socketsIndex),
String.format(
"Labeled measurement should show %d sockets (increased from %d)",
expectedReportedSockets, actualSockets));
expectedReportedSockets, startingSockets));
}
}
14 changes: 14 additions & 0 deletions swatch-tally/ct/java/utils/TallyHbiDbSeeder.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@
*/
public final class TallyHbiDbSeeder {

// separate functionality of the Seeding, DB connection, and HBI into different classes
// Need to be specific about what kind of RHEL host we are creating, so we can use the correct one
// Need to specify what facts per RHEL host ( factory for the RHEL host )
/*example for Kartik
* public HostBuilder rhelHost(String orgId) {
return new HostBuilder(orgId, true);
}

public HostBuilder cloudHost(String orgId) {
return new HostBuilder(orgId, false).cloudProvider("aws");
}
* */

private final DatabaseService hbiDatabase;

// Default values for test hosts
Expand Down Expand Up @@ -192,6 +205,7 @@ public CloudHostBuilder cloudHost(String orgId) {
* Builder for RHEL hosts. Defaults to physical infrastructure; call {@link #cloudProvider} to
* create a "RHEL on cloud" host (virtual infrastructure with cloud provider metadata).
*/
// the host
public class RhelHostBuilder {
private final String orgId;
private String inventoryId;
Expand Down
Loading
Loading