SAS 9.4 Unit Testing

Like many Systems Administrators, I’ve written countless shell scripts over the years. Often times these scripts are “check” scripts to validate that something does what I think it should do such as software functioning properly post-installation. Other times they’re used to effectively regression test the system configuration after a change, such as applying OS patches.

When it comes to SAS systems, there are numerous pieces an Administrator should validate to ensure the platform is fully functional. These validations are especially important immediately after the SAS Install and Config, but also as an ongoing concern. As someone who is very comfortable in the OS shell, I prefer to do as much of my validation work there as possible. I recently discovered the Bash Automated Testing System (BATS). BATS allows me to easily write Bash Shell based test cases that are simple and repeatable. I’ve combined BATS with Ansible to create a strong systems configuration management and validation toolkit. Below is an intro to BATS and how I am using it. 

Full instructions on how to install and use BATS are found at the BATS GitHub site: https://github.com/bats-core/bats-core

To install on Linux, simply do:

$ git clone https://github.com/bats-core/bats-core.git
$ cd bats-core
$ ./install.sh /usr/local

Substitute /usr/local for your preferred target location and put it in your PATH env variable

At this point you can start writing and using your own BATS test scripts. The idea of Unit Testing is generally applied to software development, but I’m using it to help protect against configuration drift so ongoing updates to a system or platform do not break existing SAS functionality. A couple of examples could be a change to the location or permissions of the SAS WORK filesystem or an update to database client software that changes the path to the libraries upon which SAS depends.

The goal of writing these scripts is to create simple tests that quickly measure or verify a distinct piece of functionality and once configured properly, should always succeed. Here’s an example BATS script:

#!/usr/bin/env bats

SASROOT=/opt/app/sas/9.4/install/SASFoundation/9.4
SASEXE=$SASROOT/sas
TESTDIR=/home/shayes/sas_unit_tests/tests

cd $TESTDIR

@test "Base SAS execution" {
run $SASEXE $TESTDIR/base_test.sas
[ $status -eq 0 ] }

@test "Validate -WORK /opt/app/sas/saswork_ssd" {
run $SASEXE $TESTDIR/work_test.sas
( grep 'WORK=/opt/app/sas/saswork_ssd/' work_test.log )
}

# If connection error, that proves ACCESS engine is functional
#
@test "SAS/ACCESS for Oracle functionality" {
run $SASEXE -log $BATS_TMPDIR/ora_test.log $TESTDIR/ora_test.sas
[ $status -eq 0 ] ( grep 'NOTE: Libref A1 was successfully assigned as follows:' \
$BATS_TMPDIR/ora_test.log ) || \
( grep 'ERROR: ORACLE connection error: ORA-12545' $BATS_TMPDIR/ora_test.log )
}

Executing that script gives the following output:

[shayes@sastest]$ bats sas_foundation.bats
✓ Base SAS execution
✓ Validate -WORK /opt/app/sas/saswork_ssd
✓ SAS/ACCESS for Oracle functionality

3 tests, 0 failures

If for some reason someone unmounted the /opt/app/sas/saswork_ssd filesystem without telling me, I would get:

[shayes@sastest]$ bats sas_foundation.bats
✓ Base SAS execution
✗ Validate -WORK /opt/app/sas/saswork_ssd
(in test file sas_foundation.bats, line 15)
`run $SASEXE $TESTDIR/work_test.sas' failed
✓ SAS/ACCESS for Oracle functionality

3 tests, 1 failure

Depending on the terminal settings, the failed test may show up as red and failure at the end is also highlighted. This gives an easy way to focus on the error and investigate.

The tests themselves are simple SAS programs that are run and then the logs are parsed for lines reflecting success. If those lines are not found, the test fails. The Validate WORK test uses the following sas program:

proc options option=work; run;

We then check the log for WORK=/opt/app/sas/saswork_ssd/ in the proc options option=work output. If it’s there, success. Otherwise, fail. The reason for failure could be many things such as a missing filesystem or that it’s not writable. Whatever it is, we need to investigate and resolve the issue.

The same is true for the ora_test.sas program. It simply attempts to assign a libname:

libname a1 oracle;

We expect this program to produce ERROR’s in the SAS log given it is missing many of the required parameters. However we are looking for a specific connection error and if we find that it means the SAS/ACCESS engine is successfully communicating with the Oracle client libraries which is the purpose of the test. This test could be enhanced to include real connection parameters if so desired.

These are simple validations of very basic SAS functionality, but once established, they should always succeed. That fact makes them valuable to check functionality after making changes to config files, to filesystems, applying OS patches or SAS hotfixes, and many other scenarios.

About the author: Spencer Hayes

Has one comment to “SAS 9.4 Unit Testing”

You can leave a reply or Trackback this post.
  1. Don Hayes - February 16, 2018 Reply

    This was very impressive!

Leave a Reply

Your email address will not be published.Email address is required.