Skip to content

Commit

Permalink
Merge pull request #26 from Ibvt/testsuite_solve
Browse files Browse the repository at this point in the history
make datahandling test more general, rather than for internal processing
  • Loading branch information
riasc authored Mar 2, 2025
2 parents 995cb80 + 0b5235a commit cd9e671
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 96 deletions.
19 changes: 15 additions & 4 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,28 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: extract version
- name: Determine target repository and version
id: extract_version
run: |
VERSION=${GITHUB_REF#refs/tags/}
echo "::set-output name=VERSION::$VERSION"
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
REPO="cobirna/rnanue" # production repo
TAGS="$REPO:$VERSION,$REPO:latest" # push both tags
else
VERSION="dev" # development/test tag
REPO="cobirna/rnanue-dev" # development/test repo for PRs
TAGS="$REPO:latest" # only update 'latest' tag
fi
echo "VERSION=$VERSION"
echo "REPO=$REPO"
echo "TAGS=$TAGS"
echo "TAGS=$TAGS" >> $GITHUB_ENV
- name: build and push
uses: docker/build-push-action@v4
with:
context: "{{defaultContext}}"
platforms: linux/amd64, linux/arm64
push: true
tags: cobirna/rnanue:${{ steps.extract_version.outputs.VERSION }}, cobirna/rnanue:latest
tags: ${{ env.TAGS }}

7 changes: 3 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
############################################################

# set the base image to debian
FROM ubuntu:23.04
FROM ubuntu:22.04
# tag version (extract from Config.h)
ARG VERSION=v0.2.0
# file author
Expand Down Expand Up @@ -45,13 +45,12 @@ RUN make && make install

# retrieve RNAnue
WORKDIR /
RUN git clone https://github.com/Ibvt/RNAnue.git
WORKDIR /RNAnue
COPY . /RNAnue

# retrieve SeqAn3
RUN curl -L https://github.com/seqan/seqan3/releases/download/3.3.0/seqan3-3.3.0-Source.tar.xz -o seqan3-3.3.0-Source.tar.xz
RUN tar -xvf seqan3-3.3.0-Source.tar.xz && rm seqan3-3.3.0-Source.tar.xz
RUN mv seqan3-3.3.0-Source seqan3
RUN mv seqan3-3.3.0-Source /RNAnue/seqan3

# install RNAnue
WORKDIR /RNAnue/build
Expand Down
118 changes: 110 additions & 8 deletions test/DataHandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <boost/test/unit_test.hpp>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <boost/property_tree/ptree.hpp>

// Class
#include "Base.hpp"
Expand All @@ -18,15 +19,111 @@
// namespace
namespace po = boost::program_options;
namespace fs = boost::filesystem;
namespace pt = boost::property_tree;

bool compareFiles(const fs::path& p1, const fs::path& p2) {
std::ifstream ifs1(p1.string());
std::ifstream ifs2(p2.string());
/*
* Prints property tree
*/
void printTree(const pt::ptree& tree) {
std::ostringstream oss;
pt::write_json(oss, tree);
std::cout << oss.str() << std::endl;
}

/*
* Checks if a string is a subset of another string
*/
bool isSubpath(const std::string& subpath, const std::string& superpath) {
// check if subpath is a subset of superpath
return superpath.find(subpath) != std::string::npos;
}

void processDataStructure(const std::string& readtype, pt::ptree& tree,
std::vector<std::string>& input,
std::vector<std::string>& output,
std::vector<std::string>& conds) {

for (auto &elem: tree) {
conds.push_back(elem.second.get<std::string>("condition"));
pt::ptree samples = elem.second.get_child("samples");

std::istream_iterator<char> b1(ifs1), e1;
std::istream_iterator<char> b2(ifs2), e2;
for(auto& sample : samples) {
input.push_back(sample.second.get<std::string>("input.forward"));
output.push_back(sample.second.get<std::string>("output.forward"));

BOOST_CHECK_EQUAL_COLLECTIONS(b1, e1, b2, e2);
if(readtype == "PE") {
input.push_back(sample.second.get<std::string>("input.reverse"));
output.push_back(sample.second.get<std::string>("R1only"));
output.push_back(sample.second.get<std::string>("R2only"));
output.push_back(sample.second.get<std::string>("R1unmerged"));
output.push_back(sample.second.get<std::string>("R2unmerged"));
}
}
}
}

/*
* Compares the data structure files (.json) generated by the data class
*/
bool compareDataStructureFiles(const fs::path& ref, const fs::path& gen, std::string& subcall, std::string& readtype) {
std::ifstream ifref(ref.string());
std::ifstream ifgen(gen.string());
pt::ptree pref, pgen;
pt::read_json(ifref, pref); // load file into property tree
pt::read_json(ifgen, pgen); // load file into property tree
ifref.close();
ifgen.close();

std::map<std::string, std::pair<pt::ptree, pt::ptree>> dataStructure;
dataStructure.insert(std::make_pair("ctrls", std::make_pair(
pref.get_child(subcall).get_child("ctrls"),
pgen.get_child(subcall).get_child("ctrls")
)));
dataStructure.insert(std::make_pair("trtms", std::make_pair(
pref.get_child(subcall).get_child("trtms"),
pgen.get_child(subcall).get_child("trtms")
)));

// reference/generate for comparison (first = reference, second = generated)
std::pair<std::vector<std::string>, std::vector<std::string>> conds;
std::pair<std::vector<std::string>, std::vector<std::string>> input, output;

for(auto& readtype : dataStructure) { // iterate through
pt::ptree &treeP1 = readtype.second.first; // reference (ground truth)
pt::ptree &treeP2 = readtype.second.second; // generated file for testing

processDataStructure(readtype.first, treeP1, input.first, output.first, conds.first);
processDataStructure(readtype.first, treeP2, input.second, output.second, conds.second);

}

BOOST_TEST_CONTEXT("Testing if conditions in the input files (subfolders in ctrls, trtms) have been identified correctly") {
BOOST_CHECK_EQUAL(conds.first.size(), conds.second.size());
BOOST_TEST_MESSAGE("reference: " << conds.first.size() << "\ngenerated: " << conds.second.size() << "\nThis counts conditions in ctrls and trtms separately");
// check if condition vectors are equal
BOOST_CHECK_EQUAL_COLLECTIONS(conds.first.begin(), conds.first.end(), conds.second.begin(), conds.second.end());
for(unsigned int i = 0; i < conds.first.size(); i++) {
std::cout << conds.first[i] << " == " << conds.second[i] << "\n";
}
}

BOOST_TEST_CONTEXT("Testing if the input files have been identified correctly") {
BOOST_CHECK_EQUAL(input.first.size(), input.second.size());
BOOST_TEST_MESSAGE("number of reference input files: " << input.first.size() << "\nnumber of generated input files: " << input.second.size());
for(unsigned int i = 0; i < input.first.size(); i++) {
BOOST_CHECK(isSubpath(input.first[i], input.second[i]));
}
}

BOOST_TEST_CONTEXT("Testing if the output files have been identified correctly") {
BOOST_CHECK_EQUAL(input.first.size(), input.second.size());
BOOST_TEST_MESSAGE("number of reference output files: " << input.first.size() << "\nnumber of generated output files: " << input.second.size());
for(unsigned int i = 0; i < input.first.size(); i++) {
BOOST_CHECK(isSubpath(input.first[i], input.second[i]));
}
}

return true;
}

BOOST_AUTO_TEST_CASE(DataHandlingPreprocSE) {
Expand All @@ -49,7 +146,10 @@ BOOST_AUTO_TEST_CASE(DataHandlingPreprocSE) {
// compare files
fs::path ref{testdir / "data" / "datahandling" / "dataPreprocSE.json"}; // ground truth
fs::path res{outdir / "data.json"}; // generated data file
compareFiles(ref, res);

std::string subcall = "preproc";
std::string readtype = "SE";
compareDataStructureFiles(ref, res, subcall, readtype);
}

BOOST_AUTO_TEST_CASE(DataHandlingPreprocPE) {
Expand All @@ -72,5 +172,7 @@ BOOST_AUTO_TEST_CASE(DataHandlingPreprocPE) {
// compare files
fs::path ref{testdir / "data" / "datahandling" / "dataPreprocPE.json"}; // ground truth
fs::path res{outdir / "data.json"}; // generated data file
compareFiles(ref, res);
std::string subcall = "preproc";
std::string readtype = "PE";
compareDataStructureFiles(ref, res, subcall, readtype);
}
Loading

0 comments on commit cd9e671

Please sign in to comment.