Exemplo n.º 1
0
 @Test(description = "Create an environment")
 public void test_enviornmentCreate() {
   HammerEnvironment env = new HammerEnvironment(cli_worker, name);
   exec_result = env.cli_create();
   Assert.assertTrue(exec_result.getExitCode().intValue() == 0, "Check - return code");
   Assert.assertTrue(
       getOutput(exec_result).equals(HammerEnvironment.OUT_CREATE),
       "Check - returned output string");
 }
Exemplo n.º 2
0
 // TODO: search, page, order
 @Test(
     description = "List environments. Check if updated name is present",
     dependsOnMethods = {"test_environmentUpdate"})
 public void test_environmentList() {
   HammerEnvironment env = new HammerEnvironment(cli_worker, newName);
   exec_result = env.cli_list(null, null, null);
   Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");
   Assert.assertTrue(
       getOutput(exec_result).contains(newName), "Check - updated domain name is listed");
   Assert.assertFalse(getOutput(exec_result).contains(name), "Check - previous namenot present");
 }
Exemplo n.º 3
0
 @Test(
     description = "Create duplicate environment",
     dependsOnMethods = {"test_enviornmentCreate"})
 public void test_duplicateEnvironmentCreate() {
   // Duplicate name
   HammerEnvironment env = new HammerEnvironment(cli_worker, name);
   exec_result = env.cli_create();
   Assert.assertTrue(exec_result.getExitCode().intValue() == 65, "Check - error code");
   Assert.assertTrue(
       getOutput(exec_result).equals(HammerEnvironment.ERR_DUPLICATE_NAME),
       "Check - returned output string");
 }
Exemplo n.º 4
0
  @Test(description = "8782a6e0-f41a-48d5-8599-bfe7f24078f6")
  public void test_errataList() {
    KatelloErrata errata = new KatelloErrata(org_name, product_name, repo_name, content_view);
    errata.setProductId(product_Id);

    exec_result = errata.cli_list();
    Assert.assertTrue(
        exec_result.getExitCode().intValue() == 0, "Check - return code (errata list)");
    Assert.assertTrue(
        getOutput(exec_result).replaceAll("\n", "").contains(PromoteErrata.ERRATA_ZOO_SEA),
        "Check - errata list output");
  }
Exemplo n.º 5
0
  @Test(description = "2542ae61-8de6-40ce-866f-999c39fa9018")
  public void test_errataInfo() {
    KatelloErrata errata = new KatelloErrata(org_name, product_name, repo_name, content_view);
    errata.setId(PromoteErrata.ERRATA_ZOO_SEA);
    errata.setProductId(product_Id);

    exec_result = errata.info();
    Assert.assertTrue(
        exec_result.getExitCode().intValue() == 0, "Check - return code (errata info)");
    Assert.assertTrue(
        getOutput(exec_result).replaceAll("\n", "").contains(PromoteErrata.ERRATA_ZOO_SEA),
        "Check - errata info output");
  }
  // ** ** ** ** ** ** **
  // ASSERTS
  // ** ** ** ** ** ** **
  public void asserts_create() {
    SSHCommandResult res;
    if (this.id == null) updateIDs();

    // asserts: activation_key list
    res = list(this.environment);
    Assert.assertTrue(
        res.getExitCode().intValue() == 0, "Check - return code (activation_key list)");
    String REGEXP_AK_LIST =
        ".*Id\\s*:\\s*\\d+.*Name\\s*:\\s*%s.*Environment Id\\s*:\\s*%s.*System Template Id\\s*:\\s*%s.*";

    String match_info =
        String.format(REGEXP_AK_LIST, this.name, this.environment_id, this.template_id)
            .replaceAll("\"", "");
    if (this.template_id == null) {
      match_info =
          String.format(REGEXP_AK_LIST, this.name, this.environment_id, "None")
              .replaceAll("\"", "");
    }
    Assert.assertTrue(
        KatelloCliTestScript.sgetOutput(res).replaceAll("\n", "").matches(match_info),
        String.format("Activation key [%s] should be found in the list", this.name));

    // asserts: activation_key info
    res = info();
    Assert.assertTrue(
        res.getExitCode().intValue() == 0, "Check - return code (activation_key info)");
    String REGEXP_AK_INFO =
        ".*Id\\s*:\\s*\\d+.*Name\\s*:\\s*%s.*Usage Limit\\s*:\\s*%s.*Environment Id\\s*:\\s*%s.*System Template Id\\s*:\\s*%s.*Pools\\s*:.*";
    match_info =
        String.format(
                REGEXP_AK_INFO,
                this.name,
                (this.limit != null ? this.limit : "unlimited"),
                this.environment_id,
                this.template_id)
            .replaceAll("\"", "");
    if (this.template_id == null) {
      match_info =
          String.format(
                  REGEXP_AK_INFO,
                  this.name,
                  (this.limit != null ? this.limit : "unlimited"),
                  this.environment_id,
                  "None")
              .replaceAll("\"", "");
    }
    Assert.assertTrue(
        KatelloCliTestScript.sgetOutput(res).replaceAll("\n", "").matches(match_info),
        String.format("Activation key [%s] should contain correct info", this.name));
  }
Exemplo n.º 7
0
 // TODO: update using ID of the environment
 @Test(
     description = "update previously created environment",
     dependsOnMethods = {"test_environmentInfo"})
 public void test_environmentUpdate() {
   String uid = KatelloUtils.getUniqueID();
   HammerEnvironment env = new HammerEnvironment(cli_worker, name);
   newName = "newName" + uid;
   exec_result = env.update(newName);
   Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");
   Assert.assertTrue(
       getOutput(exec_result).contains(HammerEnvironment.OUT_UPDATE),
       "Check - returned output string");
   env.name = newName;
   assert_EnvironmentInfo(env);
 }
Exemplo n.º 8
0
  @BeforeClass(description = "init: create org stuff")
  public void setUp() {
    SSHCommandResult res;
    String uid = KatelloUtils.getUniqueID();
    this.organization = "ak-" + uid;
    this.env = "ak-" + uid;

    KatelloOrg org = new KatelloOrg(this.organization, null);
    res = org.cli_create();
    Assert.assertTrue(res.getExitCode().intValue() == 0, "Check - return code");
    KatelloEnvironment env =
        new KatelloEnvironment(this.env, null, this.organization, KatelloEnvironment.LIBRARY);
    res = env.cli_create();
    Assert.assertTrue(res.getExitCode().intValue() == 0, "Check - return code");
  }
Exemplo n.º 9
0
 // TODO: delete environment by ID
 @Test(
     description = "delete environment",
     dependsOnMethods = {"test_environmentList"})
 public void test_environmentDelete() {
   HammerEnvironment env = new HammerEnvironment(cli_worker, newName);
   exec_result = env.delete();
   Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");
   Assert.assertTrue(
       getOutput(exec_result).contains(HammerEnvironment.OUT_DELETE),
       "Check - returned output string");
   // should not be listed
   exec_result = env.cli_list(null, null, null);
   Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");
   Assert.assertFalse(
       getOutput(exec_result).contains(newName), "Check - deleted domain is not listed");
 }
Exemplo n.º 10
0
  private void assert_EnvironmentInfo(HammerEnvironment env) {

    exec_result = env.cli_info();
    if (exec_result.getExitCode().intValue() == 0) {
      String match_info =
          String.format(HammerEnvironment.REG_ENVIRONMENT_INFO, env.name).replaceAll("\"", "");
      log.finest(String.format("Environment (info) match regex: [%s]", match_info));
      Assert.assertTrue(
          getOutput(exec_result).replaceAll("\n", " ").matches(match_info),
          "Environment info should match the provided info");
    } else {
      Assert.assertTrue(exec_result.getExitCode().intValue() == 128, "Check - error code");
      Assert.assertTrue(
          getOutput(exec_result).equals(HammerEnvironment.ERR_404),
          "Check - returned output string");
    }
  }
Exemplo n.º 11
0
  @BeforeClass(description = "Generate unique objects")
  public void setUp() {
    String uid = KatelloUtils.getUniqueID();
    org_name = "org" + uid;
    provider_name = "provider" + uid;
    product_name = "product" + uid;
    repo_name = "repo" + uid;
    env_name = "env" + uid;

    // Create org:
    KatelloOrg org = new KatelloOrg(this.org_name, "Package tests");
    exec_result = org.cli_create();
    Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");

    // Create provider:
    KatelloProvider prov = new KatelloProvider(provider_name, org_name, "Package provider", null);
    exec_result = prov.create();
    Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");

    // Create product:
    KatelloProduct prod =
        new KatelloProduct(product_name, org_name, provider_name, null, null, null, null, null);
    exec_result = prod.create();
    Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");

    exec_result = prod.cli_list();
    product_Id = KatelloCli.grepCLIOutput("ID", getOutput(exec_result).trim(), 1);

    KatelloRepo repo =
        new KatelloRepo(repo_name, org_name, product_name, REPO_INECAS_ZOO3, null, null);
    exec_result = repo.create();
    Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");

    KatelloEnvironment env =
        new KatelloEnvironment(env_name, null, org_name, KatelloEnvironment.LIBRARY);
    exec_result = env.cli_create();
    Assert.assertTrue(exec_result.getExitCode() == 0, "Check - return code");

    prov.synchronize();

    content_view =
        KatelloUtils.promoteRepoToEnvironment(org_name, product_name, repo_name, env_name);
  }
Exemplo n.º 12
0
  @Test(
      description =
          "Tests creating activation key by providing name got from i18n messages.properties.")
  public void test_createAKLocale() {
    String uid = KatelloUtils.getUniqueID();
    String akName = KatelloCliTestScript.getText("ak.name") + uid;
    SSHCommandResult res;

    KatelloActivationKey ak =
        new KatelloActivationKey(
            this.organization, this.env, akName, "Activation key to with localized name", null);
    res = ak.create();
    Assert.assertTrue(
        res.getExitCode().intValue() == 0, "Check - return code (activation_key create)");
  }
Exemplo n.º 13
0
 /**
  * Retrieves the IDs (or does updates) like:<br>
  * id - activation key id in DB<br>
  * environment_id - id of the environment<br>
  * template_id - id of the template (could be null)<br>
  * subscriptions - array of pool_ids (could be null)
  */
 private void updateIDs() {
   SSHCommandResult res;
   // retrieve environment_id
   if (this.environment != null) {
     KatelloEnvironment env =
         new KatelloEnvironment(this.environment, null, this.org, KatelloEnvironment.LIBRARY);
     res = env.cli_info();
     Assert.assertTrue(
         res.getExitCode().intValue() == 0, "Check - return code (environment info)");
     this.environment_id = KatelloCli.grepCLIOutput("Id", res.getStdout());
   }
   // retrieve template_id for an environment
   if (this.template != null) {
     KatelloTemplate tmpl = new KatelloTemplate(template, null, this.org, null);
     res = tmpl.info(this.environment);
     Assert.assertTrue(res.getExitCode().intValue() == 0, "Check - return code (template info)");
     this.template_id = KatelloCli.grepCLIOutput("Id", res.getStdout());
   }
   // retrieve id
   if (this.name != null) {
     res = info();
     this.id = KatelloCli.grepCLIOutput("Id", res.getStdout());
   }
 }
Exemplo n.º 14
0
  @Test(
      description = "assert rhsmd is logged to both /var/log/rhsm/rhsm.log and /var/log/messages",
      groups = {"blockedbyBug-976868"},
      enabled = true)
  // @ImplementsTCMS(id="")
  public void VerifyRhsmdForceSignalsToRhsmlogAndSyslog_Test() {
    clienttasks.register(
        sm_clientUsername,
        sm_clientPassword,
        sm_clientOrg,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        (List<String>) null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null);

    Map<String, String> signalMap = new HashMap<String, String>();
    signalMap.put("valid", "");
    signalMap.put(
        "expired",
        "This system is missing one or more subscriptions. Please run subscription-manager for more information.");
    signalMap.put(
        "warning",
        "This system's subscriptions are about to expire. Please run subscription-manager for more information.");
    signalMap.put(
        "partial",
        "This system is missing one or more subscriptions to fully cover its products. Please run subscription-manager for more information.");

    for (String signal : signalMap.keySet()) {
      String command = clienttasks.rhsmComplianceD + " -s -d -i -f " + signal;
      String marker =
          System.currentTimeMillis() + " Testing VerifyRhsmdLogsToRhsmlogAndSyslog_Test...";
      RemoteFileTasks.markFile(client, clienttasks.rhsmLogFile, marker);
      RemoteFileTasks.markFile(client, clienttasks.varLogMessagesFile, marker);

      // run and verify the command result
      String expectedStdout = "forcing status signal from cli arg";
      RemoteFileTasks.runCommandAndAssert(
          client, command, Integer.valueOf(0), expectedStdout, null);

      // verify the logs
      sleep(100); // give the message thread time to be logged
      String logResult;
      if (signalMap.get(signal).isEmpty()) {
        String unExpectedMessage = "Please run subscription-manager for more information.";
        logResult =
            RemoteFileTasks.getTailFromMarkedFile(
                    client, clienttasks.varLogMessagesFile, marker, null)
                .trim();
        Assert.assertTrue(
            !logResult.contains(unExpectedMessage),
            clienttasks.varLogMessagesFile
                + " does NOT contain message '"
                + unExpectedMessage
                + "'.");
        logResult =
            RemoteFileTasks.getTailFromMarkedFile(client, clienttasks.rhsmLogFile, marker, null)
                .trim();
        Assert.assertTrue(
            !logResult.contains(unExpectedMessage),
            clienttasks.rhsmLogFile + " does NOT contain message '" + unExpectedMessage + "'.");
        Assert.assertTrue(
            logResult.contains(expectedStdout),
            clienttasks.rhsmLogFile + " contains expected message '" + expectedStdout + "'.");

      } else {
        String expectedMessage = signalMap.get(signal);
        logResult =
            RemoteFileTasks.getTailFromMarkedFile(
                    client, clienttasks.varLogMessagesFile, marker, null)
                .trim();
        Assert.assertTrue(
            logResult.contains(expectedMessage),
            clienttasks.varLogMessagesFile
                + " contains expected message '"
                + expectedMessage
                + "'.");
        logResult =
            RemoteFileTasks.getTailFromMarkedFile(client, clienttasks.rhsmLogFile, marker, null)
                .trim();
        Assert.assertTrue(
            logResult.contains(expectedMessage),
            clienttasks.rhsmLogFile + " contains expected message '" + expectedMessage + "'.");
        Assert.assertTrue(
            logResult.contains(expectedStdout),
            clienttasks.rhsmLogFile + " contains expected message '" + expectedStdout + "'.");
      }
    }
  }
Exemplo n.º 15
0
  @Test(
      description = "assert the exit code from service rhsmcertd status when running and stopped",
      groups = {"AcceptanceTests", "blockedByBug-913118", "blockedByBug-912707"})
  protected void verifyRhsmcertdDoesNotThrowDeprecationWarnings_Test()
      throws JSONException, Exception {
    clienttasks.unregister(null, null, null);
    String marker =
        System.currentTimeMillis()
            + " Testing verifyRhsmcertdDoesNotThrowDeprecationWarnings_Test...";
    RemoteFileTasks.markFile(client, clienttasks.varLogMessagesFile, marker);

    String command = clienttasks.rhsmComplianceD + " -s";
    SSHCommandResult result = client.runCommandAndWait(command);
    Assert.assertEquals(
        result.getExitCode(), Integer.valueOf(0), "ExitCode from command '" + command + "'.");
    Assert.assertTrue(
        result.getStdout().isEmpty(), "Stdout from command '" + command + "' is empty.");
    Assert.assertTrue(
        result.getStderr().isEmpty(), "Stderr from command '" + command + "' is empty.");

    String rhsmcertdLogResult =
        RemoteFileTasks.getTailFromMarkedFile(client, clienttasks.varLogMessagesFile, marker, null)
            .trim();
    String expectedMessage =
        "In order for Subscription Manager to provide your system with updates, your system must be registered with the Customer Portal. Please enter your Red Hat login to ensure your system is up-to-date.";
    Assert.assertTrue(
        rhsmcertdLogResult.contains(expectedMessage),
        "Syslog contains expected message '" + expectedMessage + "'.");
    String unexpectedMessage = "DeprecationWarning";
    Assert.assertTrue(
        !rhsmcertdLogResult.contains(unexpectedMessage),
        "Syslog does not contain message '" + unexpectedMessage + "'.");

    clienttasks.register(
        sm_clientUsername,
        sm_clientPassword,
        sm_clientOrg,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        (List<String>) null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null);
    /*
    List<SubscriptionPool> pools = clienttasks.getCurrentlyAvailableSubscriptionPools();
    if (pools.isEmpty()) throw new SkipException("Cannot randomly pick a pool for subscribing when there are no available pools for testing.");
    SubscriptionPool pool = pools.get(randomGenerator.nextInt(pools.size())); // randomly pick a pool
    clienttasks.subscribe(null,null,pool.poolId,null,null,null,null,null,null,null,null);
    */
    clienttasks.subscribeToTheCurrentlyAvailableSubscriptionPoolsCollectively();
    // TODO: I can only seem to reproduce the error after consuming an entitlement from stage -
    // don't know why - maybe it requires an entitlement with a warning period - let's just
    // subscribe to all the pools.
    result = client.runCommandAndWait(command);
    //	[root@rhsm-accept-rhel5 ~]# /usr/libexec/rhsmd -s
    //	/usr/lib64/python2.4/site-packages/rhsm/certificate.py:123: DeprecationWarning: Call to
    // deprecated function: hasNow
    //	  category=DeprecationWarning)
    //	[root@rhsm-accept-rhel5 ~]#
    Assert.assertEquals(
        result.getExitCode(), Integer.valueOf(0), "ExitCode from command '" + command + "'.");
    Assert.assertTrue(
        result.getStdout().isEmpty(), "Stdout from command '" + command + "' is empty.");
    Assert.assertTrue(
        result.getStderr().isEmpty(), "Stderr from command '" + command + "' is empty.");
  }
Exemplo n.º 16
0
  @Test(
      description =
          "subscription-manager: subscribe to each pool with the same stacking_id to achieve compliance",
      enabled = true,
      groups = {
        "AcceptanceTests",
        "blockedByBug-739671",
        "blockedByBug-740377",
        "blockedByBug-861993",
        "blockedByBug-955142"
      },
      dataProvider = "getAvailableStackableAttributeSubscriptionPoolsData")
  // @ImplementsNitrateTest(caseId=)
  public void StackEachPoolToAchieveAttributeCompliance_Test(
      Object bugzilla, String attribute, List<SubscriptionPool> stackableAttributeSubscriptionPools)
      throws JSONException, Exception {

    // The strategy in this test is to simulate the facts on the systems so that the attribute being
    // tested ("cores","ram",or "sockets")
    // will achieve full compliance for all of the provided products after attaching a quantity of
    // one entitlement
    // from each pool in the list of stackable subscription pools.  As wee incrementally attach from
    // each pool, we will assert
    // a partial compliance until the final subscription is attached which should achieve full
    // compliance.

    // loop through the pools to determine the minimum attribute count for which one
    // of each stackable pool is needed to achieve compliance of the provided products
    // also keep a list of all the provided productIds
    Integer minimumAttributeValue = 0;
    Integer minimumSocketsValue = 0;
    Set<String> productIdsProvidedForByAllStackableSubscriptionPools = new HashSet<String>();
    Map<String, Integer> poolProductAttributeValueMap = new HashMap<String, Integer>();
    for (SubscriptionPool pool : stackableAttributeSubscriptionPools) {
      String attributeValue =
          CandlepinTasks.getPoolProductAttributeValue(
              sm_clientUsername, sm_clientPassword, sm_serverUrl, pool.poolId, attribute);
      productIdsProvidedForByAllStackableSubscriptionPools.addAll(
          CandlepinTasks.getPoolProvidedProductIds(
              sm_clientUsername, sm_clientPassword, sm_serverUrl, pool.poolId));
      minimumAttributeValue += Integer.valueOf(attributeValue);
      poolProductAttributeValueMap.put(pool.poolId, Integer.valueOf(attributeValue));
    }

    // override the system facts setting the attribute count to a value for which all the stackable
    // subscriptions are needed to achieve compliance
    Map<String, String> factsMap = new HashMap<String, String>();
    factsMap.put("memory.memtotal", "1");
    factsMap.put("cpu.cpu_socket(s)", "1");
    factsMap.put("cpu.core(s)_per_socket", "1");
    if (attribute.equals("ram")) {
      factsMap.put(
          "memory.memtotal",
          String.valueOf(
              minimumAttributeValue
                  * 1048576)); // "memory.memtotal" is stored in Kilobytes; "ram" is specified in
                               // Gigabytes; for conversions, see
                               // http://www.whatsabyte.com/P1/byteconverter.htm
    }
    if (attribute.equals("sockets")) {
      factsMap.put("cpu.cpu_socket(s)", String.valueOf(minimumAttributeValue));
    }
    if (attribute.equals("cores")) {
      if (Integer.valueOf(minimumAttributeValue) % 2
          == 0) { // configure facts for an even number of cores
        factsMap.put("cpu.core(s)_per_socket", "2");
        minimumSocketsValue = Integer.valueOf(minimumAttributeValue) / 2;
        factsMap.put("cpu.cpu_socket(s)", String.valueOf(minimumSocketsValue));
      } else { // configure facts for an odd number of cores
        factsMap.put("cpu.core(s)_per_socket", "1");
        minimumSocketsValue = Integer.valueOf(minimumAttributeValue);
        factsMap.put("cpu.cpu_socket(s)", String.valueOf(minimumSocketsValue));
      }
    }
    clienttasks.createFactsFileWithOverridingValues(factsMap);

    // register the system which has now been instrumented with facts to test the stack
    clienttasks.register(
        sm_clientUsername,
        sm_clientPassword,
        sm_clientOrg,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        (List<String>) null,
        null,
        null,
        null,
        true,
        false,
        null,
        null,
        null);

    // assert installed product status for all the products that the stacked subscriptions will
    // provide for
    List<InstalledProduct> currentlyInstalledProducts = clienttasks.getCurrentlyInstalledProducts();
    for (String productId : productIdsProvidedForByAllStackableSubscriptionPools) {
      List<InstalledProduct> installedProducts =
          InstalledProduct.findAllInstancesWithMatchingFieldFromList(
              "productId", productId, currentlyInstalledProducts);
      if (installedProducts.isEmpty()) continue; // this productIdProvidedFor is not installed
      if (installedProducts.size() > 1)
        Assert.fail(
            "Something is seriously wrong.  Found multiple InstalledProduct "
                + installedProducts
                + " with a common productId '"
                + productId
                + "'."); // this should be impossible because the would all share the same
                         // /etc/pki/product/<productId>.pem file name
      InstalledProduct installedProduct = installedProducts.get(0);
      List<String> expectedStatusDetails =
          Arrays.asList(new String[] {"Not covered by a valid subscription."});
      Assert.assertEquals(
          installedProduct.status,
          "Not Subscribed",
          "Prior to subscribing to any of the stackable subscription pools, Installed product '"
              + installedProduct.productName
              + "' which is provided for by the subscription stack should have this status.");
      if (installedProduct.statusDetails.isEmpty())
        log.warning("Status Details appears empty.  Is your candlepin server older than 0.8.6?");
      Assert.assertEquals(
          installedProduct.statusDetails,
          expectedStatusDetails,
          "Prior to subscribing to any of the stackable subscription pools, Installed product '"
              + installedProduct.productName
              + "' which is provided for by the subscription stack should have these status details: "
              + expectedStatusDetails);
      // Assert.assertTrue(isEqualNoOrder(installedProduct.statusDetails,expectedStatusDetails),"Prior to subscribing to any of the stackable subscription pools, Installed product '"+installedProduct.productName+"' which is provided for by the subscription stack should have these status details: "+expectedStatusDetails);
    }

    // incrementally attach one entitlement from each pool in the stack asserting the installed
    // product's status and details along the way
    // the final attachment should achieve full compliance for the provided products in the stack
    int s = 0;
    Integer attributeValueStackedThusFar = 0;
    Integer socketsValueStackedThusFar = 0;
    Set<String> productIdsProvidedForThusFar = new HashSet<String>();
    for (SubscriptionPool pool : stackableAttributeSubscriptionPools) {
      clienttasks.subscribe(
          null, null, pool.poolId, null, null, null, null, null, null, null, null);

      // add some test coverage for bugs 861993 and 955142
      EntitlementCert entitlementCert =
          clienttasks.getEntitlementCertCorrespondingToSubscribedPool(pool);
      if (attribute.equals("ram")) {
        Assert.assertEquals(
            entitlementCert.orderNamespace.ramLimit,
            poolProductAttributeValueMap.get(pool.poolId).toString(),
            "rct cat-cert tool reports the expected RAM Limit value in the Order for subscription '"
                + pool.subscriptionName
                + "'.");
      }
      if (attribute.equals("sockets")) {
        Assert.assertEquals(
            entitlementCert.orderNamespace.socketLimit,
            poolProductAttributeValueMap.get(pool.poolId).toString(),
            "rct cat-cert tool reports the expected Socket Limit value in the Order for subscription '"
                + pool.subscriptionName
                + "'.");
      }
      if (attribute.equals("cores")) {
        Assert.assertEquals(
            entitlementCert.orderNamespace.coreLimit,
            poolProductAttributeValueMap.get(pool.poolId).toString(),
            "rct cat-cert tool reports the expected Core Limit value in the Order for subscription '"
                + pool.subscriptionName
                + "'.");
      }

      // keep a running total of how much of the stackable attribute our entitlements have covered
      // thus far
      attributeValueStackedThusFar += poolProductAttributeValueMap.get(pool.poolId);

      // special case: when testing cores, we also need to track the sockets stacked thus far since
      // the subscription may potentially includes a sockets attribute too
      if (attribute.equals("cores")) {
        String socketsValue =
            CandlepinTasks.getPoolProductAttributeValue(
                sm_clientUsername, sm_clientPassword, sm_serverUrl, pool.poolId, "sockets");
        if (socketsValue != null) {
          socketsValueStackedThusFar += Integer.valueOf(socketsValue);
        }
      }

      // keep a running set of which productIdsProvidedFor have been covered by the subscriptions
      // thus far
      productIdsProvidedForThusFar.addAll(
          CandlepinTasks.getPoolProvidedProductIds(
              sm_clientUsername, sm_clientPassword, sm_serverUrl, pool.poolId));

      if (++s
          < stackableAttributeSubscriptionPools
              .size()) { // are we still indexing through each pool in the stack (therefore
                         // partially compliant)?

        // assert the installed products that have been provided for by the stack of subscriptions
        // thus far are Partially Subscribed
        for (InstalledProduct installedProduct : clienttasks.getCurrentlyInstalledProducts()) {
          if (productIdsProvidedForThusFar.contains(installedProduct.productId)) {
            List<String> expectedStatusDetails = new ArrayList<String>();
            if (attribute.equals("ram")) {
              expectedStatusDetails.add(
                  String.format(
                      "Only covers %sGB of %sGB of RAM.",
                      attributeValueStackedThusFar, minimumAttributeValue));
            }
            if (attribute.equals("sockets")) {
              expectedStatusDetails.add(
                  String.format(
                      "Only covers %s of %s sockets.",
                      attributeValueStackedThusFar, minimumAttributeValue));
            }
            if (attribute.equals("cores")) {
              expectedStatusDetails.add(
                  String.format(
                      "Only covers %s of %s cores.",
                      attributeValueStackedThusFar, minimumAttributeValue));
            }
            if (attribute.equals("cores")
                && socketsValueStackedThusFar > 0
                && socketsValueStackedThusFar
                    < minimumSocketsValue) { // when a cores stack also includes sockets, we will
                                             // have more status details
              expectedStatusDetails.add(
                  String.format(
                      "Only covers %s of %s sockets.",
                      socketsValueStackedThusFar, minimumSocketsValue));
            }
            if (installedProduct.statusDetails.isEmpty())
              log.warning(
                  "Status Details appears empty.  Is your candlepin server older than 0.8.6?");
            Assert.assertEquals(
                installedProduct.status,
                "Partially Subscribed",
                "After an incremental attachment of one stackable subscription for '"
                    + pool.subscriptionName
                    + "' poolId="
                    + pool.poolId
                    + ", Installed product '"
                    + installedProduct.productName
                    + "' which is provided for by the subscription stack should have this status.");
            Assert.assertTrue(
                isEqualNoOrder(installedProduct.statusDetails, expectedStatusDetails),
                "After an incremental attachment of one stackable subscription for '"
                    + pool.subscriptionName
                    + "' poolId="
                    + pool.poolId
                    + ", Installed product '"
                    + installedProduct.productName
                    + "' which is provided for by the subscription stack should have these status details: "
                    + expectedStatusDetails);

          } else {
            if (productIdsProvidedForByAllStackableSubscriptionPools.contains(
                installedProduct.productId)) {
              List<String> expectedStatusDetails =
                  Arrays.asList(new String[] {"Not covered by a valid subscription."});
              if (installedProduct.statusDetails.isEmpty())
                log.warning(
                    "Status Details appears empty.  Is your candlepin server older than 0.8.6?");
              Assert.assertEquals(
                  installedProduct.status,
                  "Not Subscribed",
                  "After an incremental attachment of one stackable subscription for '"
                      + pool.subscriptionName
                      + "' poolId="
                      + pool.poolId
                      + ", Installed product '"
                      + installedProduct.productName
                      + "' which is NOT YET provided for by the subscription stack THUS FAR should have this status.");
              Assert.assertEquals(
                  installedProduct.statusDetails,
                  expectedStatusDetails,
                  "After an incremental attachment of one stackable subscription for '"
                      + pool.subscriptionName
                      + "' poolId="
                      + pool.poolId
                      + ", Installed product '"
                      + installedProduct.productName
                      + "' which is NOT YET provided for by the subscription stack THUS FAR should have these status details: "
                      + expectedStatusDetails);
              // Assert.assertTrue(isEqualNoOrder(installedProduct.statusDetails,expectedStatusDetails), "After an incremental attachment of one stackable subscription for '"+pool.subscriptionName+"' poolId="+pool.poolId+", Installed product '"+installedProduct.productName+"' which is NOT YET provided for by the subscription stack THUS FAR should have these status details: "+expectedStatusDetails);
            } else {
              /* These asserts are valid, but not really relevant to this test.  Commented out to reduce noisy logging.
              List<String> expectedStatusDetails = Arrays.asList(new String[]{"Not covered by a valid subscription."});
              Assert.assertEquals(installedProduct.status,"Not Subscribed","After subscribing to stackable subscription for '"+pool.subscriptionName+"' poolId="+pool.poolId+", Installed product '"+installedProduct.productName+"' which is NOT provided for by the subscription stack should have this status.");
              Assert.assertTrue(isEqualNoOrder(installedProduct.statusDetails,expectedStatusDetails), "After subscribing to stackable subscription for '"+pool.subscriptionName+"' poolId="+pool.poolId+", Installed product '"+installedProduct.productName+"' which is NOT provided for by the subscription stack should have these status details: "+expectedStatusDetails);
              */
            }
          }
        }
      } else { // we have now attached the final entitlement (each pool in the stack has been
               // subscribed)

        // assert all of the installed products provided for by the subscription stack are now fully
        // Subscribed
        for (InstalledProduct installedProduct : clienttasks.getCurrentlyInstalledProducts()) {
          if (productIdsProvidedForByAllStackableSubscriptionPools.contains(
              installedProduct.productId)) {

            // special case: when sockets are also stacked with cores, we will have more status
            // details and may not yet have met socket compliance
            if (attribute.equals("cores")
                && socketsValueStackedThusFar > 0
                && socketsValueStackedThusFar < minimumSocketsValue) {
              List<String> expectedStatusDetails =
                  Arrays.asList(
                      new String[] {
                        String.format(
                            "Only covers %s of %s sockets.",
                            socketsValueStackedThusFar, minimumSocketsValue)
                      });
              if (installedProduct.statusDetails.isEmpty())
                log.warning(
                    "Status Details appears empty.  Is your candlepin server older than 0.8.6?");
              Assert.assertEquals(
                  installedProduct.status,
                  "Partially Subscribed",
                  "After attaching the final stackable subscription for '"
                      + pool.subscriptionName
                      + "' poolId="
                      + pool.poolId
                      + ", all system cores should be covered excepty sockets for Installed product '"
                      + installedProduct.productName
                      + "'.");
              Assert.assertEquals(
                  installedProduct.statusDetails,
                  expectedStatusDetails,
                  "After attaching the final stackable subscription for '"
                      + pool.subscriptionName
                      + "' poolId="
                      + pool.poolId
                      + ", all system cores should be covered except sockets for Installed product '"
                      + installedProduct.productName
                      + "'.  Expecting status details: "
                      + expectedStatusDetails);
              // Assert.assertTrue(isEqualNoOrder(installedProduct.statusDetails,expectedStatusDetails), "After subscribing to stackable subscription pool '"+pool.subscriptionName+"' id="+pool.poolId+", All system cores should be covered, but not the sockets for Installed product '"+installedProduct.productName+"'.  Expecting status details: "+expectedStatusDetails);
            } else {

              // assert this installed product is now fully subscribed
              Assert.assertEquals(
                  installedProduct.status,
                  "Subscribed",
                  "After incrementally attaching the final stackable subscription for '"
                      + pool.subscriptionName
                      + "' poolId="
                      + pool.poolId
                      + ", Installed product '"
                      + installedProduct.productName
                      + "' which is provided for by the subscription stack should have this status.");
              Assert.assertTrue(
                  installedProduct.statusDetails.isEmpty(),
                  "The status details of Installed product '"
                      + installedProduct.productName
                      + "' which is fully subscribed should now be empty.");
            }
          } else {
            // installed product should be Not Subscribed since it is not affected by the consumed
            // stack of subscription
            Assert.assertEquals(
                installedProduct.status,
                "Not Subscribed",
                "The stackable subscriptions being tested do NOT provide for installed product '"
                    + installedProduct.productName
                    + "'.");
          }
        }
      }
    }
  }