<commit_before>#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TFile.h>
#include <TH1F.h>
#include <TGraph.h>
#include <TGraphErrors.h>
#include <TStyle.h>
#include <TGrid.h>
#include <TCanvas.h>
#include <TSystem.h>
#include <TLatex.h>
#include <TObjArray.h>
#include "AliCDBEntry.h"
#include "AliITSCalibrationSDD.h"
#endif

/*  $Id$    */

// Macro to plot the calibration parameters from the OCDB files
// created from PEDESTAL and PULSER runs vs. Time
// Origin: F. Prino (prino@to.infn.it)

void PlotCalibSDDVsTime(Int_t year=2010, Int_t firstRun=77677,
			Int_t lastRun=999999999){

  gStyle->SetOptTitle(0);
  gStyle->SetOptStat(0);
  gStyle->SetPadLeftMargin(0.14);
  gStyle->SetTitleOffset(1.4,"Y");

  TGrid::Connect("alien:",0,0,"t");
  gSystem->Exec(Form("gbbox find \"/alice/data/%d/OCDB/ITS/Calib/CalibSDD\" \"Run*.root\" > runCalibAlien.txt",year));
  FILE* listruns=fopen("runCalibAlien.txt","r");

  TH1F* hbase=new TH1F("hbase","",60,0.5,120.5);
  TH1F* hnoise=new TH1F("hnoise","",100,0.,7.);
  TH1F* hgain=new TH1F("hgain","",100,0.,4.);
  TH1F* hchstatus=new TH1F("hchstatus","",2,-0.5,1.5);
  TGraphErrors* gbasevstim=new TGraphErrors(0);
  TGraphErrors* gnoisevstim=new TGraphErrors(0);
  TGraphErrors* ggainvstim=new TGraphErrors(0);
  TGraphErrors* gstatvstim=new TGraphErrors(0);
  gbasevstim->SetName("gbasevstim");
  gnoisevstim->SetName("gnoisevstim");
  ggainvstim->SetName("ggainvstim");
  gstatvstim->SetName("gstatvstim");
  gbasevstim->SetTitle("Baseline vs. run");
  gnoisevstim->SetTitle("Noise vs. run");
  ggainvstim->SetTitle("Gain vs. run");
  gstatvstim->SetTitle("Good Anodes vs. run");

  Char_t filnam[200],filnamalien[200];
  Int_t iPoint=0;
  Int_t nrun,nrun2,nv,ns;

  while(!feof(listruns)){
    hbase->Reset();
    hnoise->Reset();
    hgain->Reset();
    hchstatus->Reset();
    fscanf(listruns,"%s\n",filnam);
    Char_t directory[100];
    sprintf(directory,"/alice/data/%d",year);
    if(!strstr(filnam,directory)) continue;
    sscanf(filnam,"/alice/data/%d/OCDB/ITS/Calib/CalibSDD/Run%d_%d_v%d_s%d.root",&year,&nrun,&nrun2,&nv,&ns);
    if(year==2009 && (nrun<85639 && nrun2> 85639)) continue; // protection for files with swapped ladders 4-5 of layer 3
    if(year==2009 && (nrun>100000 && nv< 184)) continue; // protection for files with swapped ladder 0-1 of layer 4
    if(year==2010 && (nrun>=114603 && nv< 98)) continue; // protection for files without treatment of masked hybrids
    if(nrun<firstRun) continue;
    if(nrun>lastRun) continue;
    sprintf(filnamalien,"alien://%s",filnam);
    printf("Open file: %s\n",filnam);
    TFile *f= TFile::Open(filnamalien);
    AliCDBEntry *ent=(AliCDBEntry*)f->Get("AliCDBEntry");
    TObjArray *calSDD = (TObjArray *)ent->GetObject();
    printf("Run %d Entries in array=%d \n",nrun,calSDD->GetEntriesFast());

    AliITSCalibrationSDD *cal;
    for(Int_t iMod=0; iMod<260;iMod++){
      cal=(AliITSCalibrationSDD*)calSDD->At(iMod);
      if(cal==0) continue;
      for(Int_t iAn=0; iAn<512; iAn++){
	Int_t ic=cal->GetChip(iAn);
	Float_t base=cal->GetBaseline(iAn);
	Float_t noise=cal->GetNoiseAfterElectronics(iAn);
	Float_t gain=cal->GetChannelGain(iAn);
	if(cal->IsBadChannel(iAn)) hchstatus->Fill(0);
	if(!cal->IsBadChannel(iAn) && !cal->IsChipBad(ic) && !cal->IsBad() ){
	  hbase->Fill(base);
	  hchstatus->Fill(1);
	  hnoise->Fill(noise);
	  hgain->Fill(gain);
	}
      }
    }
    printf("Run %d <Base> = %f <Noise> =%f Entries = %d\n",nrun,hbase->GetMean(),hnoise->GetMean(),(Int_t)hbase->GetEntries());
    if((Int_t)hbase->GetEntries()==0) continue;
    gbasevstim->SetPoint(iPoint,(Double_t)nrun,hbase->GetMean());
    gbasevstim->SetPointError(iPoint,0.,hbase->GetRMS());
    gnoisevstim->SetPoint(iPoint,(Double_t)nrun,hnoise->GetMean());
    gnoisevstim->SetPointError(iPoint,0.,hnoise->GetRMS());
    ggainvstim->SetPoint(iPoint,(Double_t)nrun,hgain->GetMean());
    ggainvstim->SetPointError(iPoint,0.,hgain->GetRMS());
    gstatvstim->SetPoint(iPoint,(Double_t)nrun,hchstatus->GetBinContent(2));
    iPoint++;
    f->Close();
  }

  TFile *ofil=new TFile(Form("Calib%dVsTime.root",year),"recreate");
  gbasevstim->Write();
  gnoisevstim->Write();
  ggainvstim->Write();
  gstatvstim->Write();
  ofil->Close();

  TCanvas* cbase=new TCanvas("cbase","Baselines");
  gbasevstim->SetFillColor(kOrange-2);
  gbasevstim->SetMarkerStyle(20);
  gbasevstim->Draw("AP3");
  gbasevstim->Draw("PLXSAME");
  gbasevstim->SetMinimum(0.);
  gbasevstim->SetMaximum(70.);
  gbasevstim->GetXaxis()->SetTitle("Run number");
  gbasevstim->GetYaxis()->SetTitle("<Baseline> (ADC counts)");
  cbase->SaveAs("BaseRun09.gif");

  TCanvas* cnoise=new TCanvas("cnoise","Noise");
  gnoisevstim->SetFillColor(kOrange-2);
  gnoisevstim->SetMarkerStyle(20);
  gnoisevstim->Draw("AP3");
  gnoisevstim->Draw("PLXSAME");
  gnoisevstim->SetMinimum(0.);
  gnoisevstim->SetMaximum(4.);
  gnoisevstim->GetXaxis()->SetTitle("Run number");
  gnoisevstim->GetYaxis()->SetTitle("<Noise> (ADC counts)");
  cnoise->SaveAs("NoiseRun09.gif");

  TCanvas* cgain=new TCanvas("cgain","Gain");
  ggainvstim->SetFillColor(kOrange-2);
  ggainvstim->SetMarkerStyle(20);
  ggainvstim->Draw("AP3");
  ggainvstim->Draw("PLXSAME");
  ggainvstim->SetMinimum(0.);
  ggainvstim->SetMaximum(4.);
  ggainvstim->GetXaxis()->SetTitle("Run number");
  ggainvstim->GetYaxis()->SetTitle("<Gain> (ADC/DAC)");
  cgain->SaveAs("GainRun09.gif");

  TCanvas* cfrac=new TCanvas("cfrac","Good channels");
  gstatvstim->SetFillColor(kOrange-2);
  gstatvstim->SetMarkerStyle(20);
  gstatvstim->Draw("AP3");
  gstatvstim->Draw("PLXSAME");
  gstatvstim->SetMinimum(100000.);
  gstatvstim->SetMaximum(133000.);
  gstatvstim->GetXaxis()->SetTitle("Run number");
  gstatvstim->GetYaxis()->SetTitle("Number of good anodes in acquisition");
  cfrac->SaveAs("GoodAnodesRun09.gif");

}
<commit_msg>New plot with fraction of good channels per layer<commit_after>#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TFile.h>
#include <TH1F.h>
#include <TGraph.h>
#include <TGraphErrors.h>
#include <TStyle.h>
#include <TGrid.h>
#include <TCanvas.h>
#include <TSystem.h>
#include <TLatex.h>
#include <TLegend.h>
#include <TLegendEntry.h>
#include <TObjArray.h>
#include "AliCDBEntry.h"
#include "AliITSCalibrationSDD.h"
#endif

/*  $Id$    */

// Macro to plot the calibration parameters from the OCDB files
// created from PEDESTAL and PULSER runs vs. Time
// Origin: F. Prino (prino@to.infn.it)

void PlotCalibSDDVsTime(Int_t year=2010, Int_t firstRun=77677,
			Int_t lastRun=999999999){

  gStyle->SetOptTitle(0);
  gStyle->SetOptStat(0);
  gStyle->SetPadLeftMargin(0.14);
  gStyle->SetTitleOffset(1.4,"Y");

  TGrid::Connect("alien:",0,0,"t");
  gSystem->Exec(Form("gbbox find \"/alice/data/%d/OCDB/ITS/Calib/CalibSDD\" \"Run*.root\" > runCalibAlien.txt",year));
  FILE* listruns=fopen("runCalibAlien.txt","r");

  TH1F* hbase=new TH1F("hbase","",60,0.5,120.5);
  TH1F* hnoise=new TH1F("hnoise","",100,0.,7.);
  TH1F* hgain=new TH1F("hgain","",100,0.,4.);
  TH1F* hchstatus=new TH1F("hchstatus","",2,-0.5,1.5);
  TH1F* hchstatus3=new TH1F("hchstatus3","",2,-0.5,1.5);
  TH1F* hchstatus4=new TH1F("hchstatus4","",2,-0.5,1.5);
  TGraphErrors* gbasevstim=new TGraphErrors(0);
  TGraphErrors* gnoisevstim=new TGraphErrors(0);
  TGraphErrors* ggainvstim=new TGraphErrors(0);
  TGraphErrors* gstatvstim=new TGraphErrors(0);
  TGraphErrors* gfracvstim=new TGraphErrors(0);
  TGraphErrors* gfrac3vstim=new TGraphErrors(0);
  TGraphErrors* gfrac4vstim=new TGraphErrors(0);
  gbasevstim->SetName("gbasevstim");
  gnoisevstim->SetName("gnoisevstim");
  ggainvstim->SetName("ggainvstim");
  gstatvstim->SetName("gstatvstim");
  gfracvstim->SetName("gfracvstim");
  gfrac3vstim->SetName("gfrac3vstim");
  gfrac4vstim->SetName("gfrac4vstim");
  gbasevstim->SetTitle("Baseline vs. run");
  gnoisevstim->SetTitle("Noise vs. run");
  ggainvstim->SetTitle("Gain vs. run");
  gstatvstim->SetTitle("Good Anodes vs. run");
  gfracvstim->SetTitle("Fraction of Good Anodes vs. run");
  gfrac3vstim->SetTitle("Fraction of Good Anodes vs. run");
  gfrac4vstim->SetTitle("Fraction of Good Anodes vs. run");

  Char_t filnam[200],filnamalien[200];
  Int_t iPoint=0;
  Int_t nrun,nrun2,nv,ns;

  while(!feof(listruns)){
    hbase->Reset();
    hnoise->Reset();
    hgain->Reset();
    hchstatus->Reset();
    hchstatus3->Reset();
    hchstatus4->Reset();
    fscanf(listruns,"%s\n",filnam);
    Char_t directory[100];
    sprintf(directory,"/alice/data/%d",year);
    if(!strstr(filnam,directory)) continue;
    sscanf(filnam,"/alice/data/%d/OCDB/ITS/Calib/CalibSDD/Run%d_%d_v%d_s%d.root",&year,&nrun,&nrun2,&nv,&ns);
    if(year==2009 && (nrun<85639 && nrun2> 85639)) continue; // protection for files with swapped ladders 4-5 of layer 3
    if(year==2009 && (nrun>100000 && nv< 184)) continue; // protection for files with swapped ladder 0-1 of layer 4
    if(year==2010 && (nrun>=114603 && nv< 98)) continue; // protection for files without treatment of masked hybrids
    if(nrun<firstRun) continue;
    if(nrun>lastRun) continue;
    sprintf(filnamalien,"alien://%s",filnam);
    printf("Open file: %s\n",filnam);
    TFile *f= TFile::Open(filnamalien);
    AliCDBEntry *ent=(AliCDBEntry*)f->Get("AliCDBEntry");
    TObjArray *calSDD = (TObjArray *)ent->GetObject();
    printf("Run %d Entries in array=%d \n",nrun,calSDD->GetEntriesFast());

    AliITSCalibrationSDD *cal;
    for(Int_t iMod=0; iMod<260;iMod++){
      cal=(AliITSCalibrationSDD*)calSDD->At(iMod);
      if(cal==0) continue;
      for(Int_t iAn=0; iAn<512; iAn++){
	Int_t ic=cal->GetChip(iAn);
	Float_t base=cal->GetBaseline(iAn);
	Float_t noise=cal->GetNoiseAfterElectronics(iAn);
	Float_t gain=cal->GetChannelGain(iAn);
	if(cal->IsBadChannel(iAn)){
	  hchstatus->Fill(0);
	  if(iMod<84) hchstatus3->Fill(0);
	  else hchstatus4->Fill(0);
	}
	if(!cal->IsBadChannel(iAn) && !cal->IsChipBad(ic) && !cal->IsBad() ){
	  hbase->Fill(base);
	  hchstatus->Fill(1);
	  if(iMod<84) hchstatus3->Fill(1);
	  else hchstatus4->Fill(1);
	  hnoise->Fill(noise);
	  hgain->Fill(gain);
	}
      }
    }
    printf("Run %d <Base> = %f <Noise> =%f Entries = %d\n",nrun,hbase->GetMean(),hnoise->GetMean(),(Int_t)hbase->GetEntries());
    if((Int_t)hbase->GetEntries()==0) continue;
    gbasevstim->SetPoint(iPoint,(Double_t)nrun,hbase->GetMean());
    gbasevstim->SetPointError(iPoint,0.,hbase->GetRMS());
    gnoisevstim->SetPoint(iPoint,(Double_t)nrun,hnoise->GetMean());
    gnoisevstim->SetPointError(iPoint,0.,hnoise->GetRMS());
    ggainvstim->SetPoint(iPoint,(Double_t)nrun,hgain->GetMean());
    ggainvstim->SetPointError(iPoint,0.,hgain->GetRMS());
    gstatvstim->SetPoint(iPoint,(Double_t)nrun,hchstatus->GetBinContent(2));
    gfracvstim->SetPoint(iPoint,(Double_t)nrun,hchstatus->GetBinContent(2)/260./512.);
    gfrac3vstim->SetPoint(iPoint,(Double_t)nrun,hchstatus3->GetBinContent(2)/84./512.);
    gfrac4vstim->SetPoint(iPoint,(Double_t)nrun,hchstatus4->GetBinContent(2)/176./512.);
    iPoint++;
    f->Close();
  }

  TFile *ofil=new TFile(Form("Calib%dVsTime.root",year),"recreate");
  gbasevstim->Write();
  gnoisevstim->Write();
  ggainvstim->Write();
  gstatvstim->Write();
  ofil->Close();

  TCanvas* cbase=new TCanvas("cbase","Baselines");
  gbasevstim->SetFillColor(kOrange-2);
  gbasevstim->SetMarkerStyle(20);
  gbasevstim->Draw("AP3");
  gbasevstim->Draw("PLXSAME");
  gbasevstim->SetMinimum(0.);
  gbasevstim->SetMaximum(70.);
  gbasevstim->GetXaxis()->SetTitle("Run number");
  gbasevstim->GetYaxis()->SetTitle("<Baseline> (ADC counts)");
  cbase->SaveAs(Form("BaseRun%d.gif",year));

  TCanvas* cnoise=new TCanvas("cnoise","Noise");
  gnoisevstim->SetFillColor(kOrange-2);
  gnoisevstim->SetMarkerStyle(20);
  gnoisevstim->Draw("AP3");
  gnoisevstim->Draw("PLXSAME");
  gnoisevstim->SetMinimum(0.);
  gnoisevstim->SetMaximum(4.);
  gnoisevstim->GetXaxis()->SetTitle("Run number");
  gnoisevstim->GetYaxis()->SetTitle("<Noise> (ADC counts)");
  cnoise->SaveAs(Form("NoiseRun%d.gif",year));

  TCanvas* cgain=new TCanvas("cgain","Gain");
  ggainvstim->SetFillColor(kOrange-2);
  ggainvstim->SetMarkerStyle(20);
  ggainvstim->Draw("AP3");
  ggainvstim->Draw("PLXSAME");
  ggainvstim->SetMinimum(0.);
  ggainvstim->SetMaximum(4.);
  ggainvstim->GetXaxis()->SetTitle("Run number");
  ggainvstim->GetYaxis()->SetTitle("<Gain> (ADC/DAC)");
  cgain->SaveAs(Form("GainRun%d.gif",year));

  TCanvas* cstatus=new TCanvas("cstatus","Good channels");
  gstatvstim->SetFillColor(kOrange-2);
  gstatvstim->SetMarkerStyle(20);
  gstatvstim->Draw("AP3");
  gstatvstim->Draw("PLXSAME");
  gstatvstim->SetMinimum(100000.);
  gstatvstim->SetMaximum(133000.);
  gstatvstim->GetXaxis()->SetTitle("Run number");
  gstatvstim->GetYaxis()->SetTitle("Number of good anodes in acquisition");
  cstatus->SaveAs(Form("GoodAnodesRun%d.gif",year));

  TCanvas* cfrac=new TCanvas("cfrac","Fraction of Good");
  gfracvstim->SetMarkerStyle(20);
  gfrac3vstim->SetMarkerStyle(22);
  gfrac3vstim->SetMarkerColor(2);
  gfrac3vstim->SetLineColor(2);
  gfrac4vstim->SetMarkerStyle(23);
  gfrac4vstim->SetMarkerColor(4);
  gfrac4vstim->SetLineColor(4);
  gfracvstim->Draw("APL");
  gfrac3vstim->Draw("PLSAME");
  gfrac4vstim->Draw("PLSAME");
  gfracvstim->SetMinimum(0.7);
  gfracvstim->SetMaximum(1.05);
  gfracvstim->GetXaxis()->SetTitle("Run number");
  gfracvstim->GetYaxis()->SetTitle("Fraction of good anodes in acquisition");
  TLegend* leg=new TLegend(0.2,0.15,0.45,0.35);
  leg->SetFillColor(0);
  TLegendEntry* entr=leg->AddEntry(gfrac3vstim,"Layer 3","P");
  entr->SetTextColor(2);
  entr=leg->AddEntry(gfrac4vstim,"Layer 4","P");
  entr->SetTextColor(4);
  entr=leg->AddEntry(gfracvstim,"All","P");
  entr->SetTextColor(1);
  leg->Draw();
  cfrac->SaveAs(Form("FractionGoodRun%d.gif",year));

}
<|endoftext|>


<commit_before>/**
 * This file is part of the CernVM File System.
 */

#include "history_sql.h"

#include <cassert>

namespace history {

const float    HistoryDatabase::kLatestSchema          = 1.0;
const float    HistoryDatabase::kLatestSupportedSchema = 1.0;
const unsigned HistoryDatabase::kLatestSchemaRevision  = 2;

/**
 * Database Schema ChangeLog:
 *
 * Schema Version 1.0
 *   -> Revision 2: add table 'recycle_bin'
 *   -> Revision 1: add field 'size'
 *
 */

const std::string HistoryDatabase::kFqrnKey = "fqrn";

/**
 * This method creates a new database file and initializes the database schema.
 */
bool HistoryDatabase::CreateEmptyDatabase() {
  assert(read_write());

  return CreateTagsTable() &&
         CreateRecycleBinTable();
}

bool HistoryDatabase::CreateTagsTable() {
  assert(read_write());
  return sqlite::Sql(sqlite_db(),
    "CREATE TABLE tags (name TEXT, hash TEXT, revision INTEGER, "
    "  timestamp INTEGER, channel INTEGER, description TEXT, size INTEGER, "
    "  CONSTRAINT pk_tags PRIMARY KEY (name))").Execute();
}

bool HistoryDatabase::CreateRecycleBinTable() {
  assert(read_write());
  return sqlite::Sql(sqlite_db(),
    "CREATE TABLE recycle_bin (hash TEXT, flags INTEGER, "
    "  CONSTRAINT pk_hash PRIMARY KEY (hash))").Execute();
}

bool HistoryDatabase::InsertInitialValues(const std::string &repository_name) {
  assert(read_write());
  return this->SetProperty(kFqrnKey, repository_name);
}

bool HistoryDatabase::ContainsRecycleBin() const {
  return schema_version() >= 1.0 - kSchemaEpsilon && schema_revision() >= 2;
}

bool HistoryDatabase::CheckSchemaCompatibility() {
  return !((schema_version() < kLatestSupportedSchema - kSchemaEpsilon) ||
           (schema_version() > kLatestSchema          + kSchemaEpsilon));
}

bool HistoryDatabase::LiveSchemaUpgradeIfNecessary() {
  assert(read_write());
  assert(IsEqualSchema(schema_version(), 1.0));

  if (schema_revision() == kLatestSchemaRevision) {
    return true;
  }

  LogCvmfs(kLogHistory, kLogDebug, "upgrading history schema revision "
                                   "%.2f (Rev: %d) to %.2f (Rev: %d)",
           schema_version(), schema_revision(),
           kLatestSchema, kLatestSchemaRevision);

  const bool success = UpgradeSchemaRevision_10_1() &&
                       UpgradeSchemaRevision_10_2();

  return success && StoreSchemaRevision();
}

bool HistoryDatabase::UpgradeSchemaRevision_10_1() {
  if (schema_revision() > 0) {
    return true;
  }

  sqlite::Sql sql_upgrade(sqlite_db(), "ALTER TABLE tags ADD size INTEGER;");
  if (!sql_upgrade.Execute()) {
    LogCvmfs(kLogHistory, kLogStderr, "failed to upgrade tags table");
    return false;
  }

  set_schema_revision(1);
  return true;
}

bool HistoryDatabase::UpgradeSchemaRevision_10_2() {
  if (schema_revision() > 1) {
    return true;
  }

  if (!CreateRecycleBinTable()) {
    LogCvmfs(kLogHistory, kLogStderr, "failed to upgrade history database");
    return false;
  }

  set_schema_revision(2);
  return true;
}

//------------------------------------------------------------------------------

#define DB_FIELDS_V1R0  "name, hash, revision, timestamp, channel, description"
#define DB_FIELDS_V1R1  "name, hash, revision, timestamp, channel, description, size"
#define DB_PLACEHOLDERS ":name, :hash, :revision, :timestamp, :channel, :description, :size"
#define ROLLBACK_COND   "(revision > :target_rev  OR " \
                        " name     = :target_name)   " \
                        "AND channel  = :target_chan "

#define MAKE_STATEMENT(STMT_TMPL, REV)                         \
static const std::string REV =                                 \
  ReplaceAll(                                                  \
    ReplaceAll(                                                \
      ReplaceAll(STMT_TMPL, "@DB_FIELDS@", DB_FIELDS_ ## REV), \
      "@DB_PLACEHOLDERS@", DB_PLACEHOLDERS),                   \
    "@ROLLBACK_COND@", ROLLBACK_COND)

#define MAKE_STATEMENTS(STMT_TMPL) \
  MAKE_STATEMENT(STMT_TMPL, V1R0); \
  MAKE_STATEMENT(STMT_TMPL, V1R1)

#define DEFERRED_INIT(DB, REV) \
  DeferredInit((DB)->sqlite_db(), (REV).c_str())

#define DEFERRED_INITS(DB) \
  if ((DB)->IsEqualSchema((DB)->schema_version(), 1.0f) && \
      (DB)->schema_revision() == 0) {                      \
    DEFERRED_INIT((DB), V1R0);                             \
  } else {                                                 \
    DEFERRED_INIT((DB), V1R1);                             \
  }

SqlInsertTag::SqlInsertTag(const HistoryDatabase *database) {
  MAKE_STATEMENTS("INSERT INTO tags (@DB_FIELDS@) VALUES (@DB_PLACEHOLDERS@);");
  DEFERRED_INITS(database);
}

bool SqlInsertTag::BindTag(const History::Tag &tag) {
  return
    BindText(1, tag.name) &&
    BindTextTransient(2, tag.root_hash.ToString()) &&  // temporary (ToString)
    BindInt64(3, tag.revision) &&
    BindInt64(4, tag.timestamp) &&
    BindInt64(5, tag.channel) &&
    BindText(6, tag.description) &&
    BindInt64(7, tag.size);
}

//------------------------------------------------------------------------------

SqlRemoveTag::SqlRemoveTag(const HistoryDatabase *database) {
  DeferredInit(database->sqlite_db(), "DELETE FROM tags WHERE name = :name;");
}

bool SqlRemoveTag::BindName(const std::string &name) {
  return BindText(1, name);
}

//------------------------------------------------------------------------------

SqlFindTag::SqlFindTag(const HistoryDatabase *database) {
  MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM tags WHERE name = :name LIMIT 1;");
  DEFERRED_INITS(database);
}

bool SqlFindTag::BindName(const std::string &name) {
  return BindText(1, name);
}

//------------------------------------------------------------------------------

SqlFindTagByDate::SqlFindTagByDate(const HistoryDatabase *database) {
  // figure out the tag that was HEAD to a given point in time
  //
  // conceptually goes back in the revision history  |  ORDER BY revision DESC
  // and picks the first tag                         |  LIMIT 1
  // that is older than the given timestamp          |  WHICH timestamp <= :ts
  MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM tags "
                  "WHERE timestamp <= :timestamp "
                  "ORDER BY revision DESC LIMIT 1;");
  DEFERRED_INITS(database);
}

bool SqlFindTagByDate::BindTimestamp(const time_t timestamp) {
  return BindInt64(1, timestamp);
}

//------------------------------------------------------------------------------

SqlCountTags::SqlCountTags(const HistoryDatabase *database) {
  DeferredInit(database->sqlite_db(), "SELECT count(*) FROM tags;");
}

unsigned SqlCountTags::RetrieveCount() const {
  int64_t count = RetrieveInt64(0);
  assert(count >= 0);
  return static_cast<uint64_t>(count);
}

//------------------------------------------------------------------------------

SqlListTags::SqlListTags(const HistoryDatabase *database) {
  MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM tags ORDER BY revision DESC;");
  DEFERRED_INITS(database);
}

//------------------------------------------------------------------------------

SqlGetChannelTips::SqlGetChannelTips(const HistoryDatabase *database) {
  MAKE_STATEMENTS("SELECT @DB_FIELDS@, MAX(revision) AS max_rev "
                  "FROM tags "
                  "GROUP BY channel;");
  DEFERRED_INITS(database);
}

SqlGetHashes::SqlGetHashes(const HistoryDatabase *database) {
  DeferredInit(database->sqlite_db(), "SELECT DISTINCT hash FROM tags "
                                      "ORDER BY revision ASC");
}

shash::Any SqlGetHashes::RetrieveHash() const {
  return shash::MkFromHexPtr(shash::HexPtr(RetrieveString(0)),
                             shash::kSuffixCatalog);
}

//------------------------------------------------------------------------------

SqlRollbackTag::SqlRollbackTag(const HistoryDatabase *database) {
  MAKE_STATEMENTS("DELETE FROM tags WHERE @ROLLBACK_COND@;");
  DEFERRED_INITS(database);
}

//------------------------------------------------------------------------------

SqlListRollbackTags::SqlListRollbackTags(const HistoryDatabase *database) {
  MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM tags "
                  "WHERE @ROLLBACK_COND@ "
                  "ORDER BY revision DESC;");
  DEFERRED_INITS(database);
}

//------------------------------------------------------------------------------

bool SqlRecycleBin::CheckSchema(const HistoryDatabase *database) const {
  return (database->IsEqualSchema(database->schema_version(), 1.0)) &&
         (database->schema_revision() >= 2);
}

//------------------------------------------------------------------------------

SqlRecycleBinInsert::SqlRecycleBinInsert(const HistoryDatabase *database) {
  assert(CheckSchema(database));
  DeferredInit(database->sqlite_db(),
               "INSERT OR IGNORE INTO recycle_bin (hash, flags) "
               "VALUES (:hash, :flags)");
}

bool SqlRecycleBinInsert::BindTag(const History::Tag &condemned_tag) {
  const unsigned int flags = SqlRecycleBin::kFlagCatalog;
  return
    BindTextTransient(1, condemned_tag.root_hash.ToString()) &&
    BindInt64(2, flags);
}

//------------------------------------------------------------------------------

SqlRecycleBinList::SqlRecycleBinList(const HistoryDatabase *database) {
  assert(CheckSchema(database));
  DeferredInit(database->sqlite_db(), "SELECT hash, flags FROM recycle_bin;");
}

shash::Any SqlRecycleBinList::RetrieveHash() {
  const unsigned int flags = RetrieveInt64(1);
  shash::Suffix suffix = shash::kSuffixNone;
  if (flags & SqlRecycleBin::kFlagCatalog) {
    suffix = shash::kSuffixCatalog;
  }

  return shash::MkFromHexPtr(shash::HexPtr(RetrieveString(0)), suffix);
}

//------------------------------------------------------------------------------

SqlRecycleBinFlush::SqlRecycleBinFlush(const HistoryDatabase *database) {
  assert(CheckSchema(database));
  DeferredInit(database->sqlite_db(), "DELETE FROM recycle_bin;");
}

//------------------------------------------------------------------------------

SqlRecycleBinRollback::SqlRecycleBinRollback(const HistoryDatabase *database) {
  assert(CheckSchema(database));
  const bool success = Init(database->sqlite_db(),
                            "INSERT OR IGNORE INTO recycle_bin (hash, flags) "
                            "SELECT hash, :flags "
                            "FROM tags WHERE " + rollback_condition + ";");
  assert(success);
}

bool SqlRecycleBinRollback::BindFlags() {
  return BindInt64(1, SqlRecycleBin::kFlagCatalog);
}

}; /* namespace history */
<commit_msg>cosmetics<commit_after>/**
 * This file is part of the CernVM File System.
 */

#include "history_sql.h"

#include <cassert>

namespace history {

const float    HistoryDatabase::kLatestSchema          = 1.0;
const float    HistoryDatabase::kLatestSupportedSchema = 1.0;
const unsigned HistoryDatabase::kLatestSchemaRevision  = 2;

/**
 * Database Schema ChangeLog:
 *
 * Schema Version 1.0
 *   -> Revision 2: add table 'recycle_bin'
 *   -> Revision 1: add field 'size'
 *
 */

const std::string HistoryDatabase::kFqrnKey = "fqrn";

/**
 * This method creates a new database file and initializes the database schema.
 */
bool HistoryDatabase::CreateEmptyDatabase() {
  assert(read_write());

  return CreateTagsTable() &&
         CreateRecycleBinTable();
}

bool HistoryDatabase::CreateTagsTable() {
  assert(read_write());
  return sqlite::Sql(sqlite_db(),
    "CREATE TABLE tags (name TEXT, hash TEXT, revision INTEGER, "
    "  timestamp INTEGER, channel INTEGER, description TEXT, size INTEGER, "
    "  CONSTRAINT pk_tags PRIMARY KEY (name))").Execute();
}

bool HistoryDatabase::CreateRecycleBinTable() {
  assert(read_write());
  return sqlite::Sql(sqlite_db(),
    "CREATE TABLE recycle_bin (hash TEXT, flags INTEGER, "
    "  CONSTRAINT pk_hash PRIMARY KEY (hash))").Execute();
}

bool HistoryDatabase::InsertInitialValues(const std::string &repository_name) {
  assert(read_write());
  return this->SetProperty(kFqrnKey, repository_name);
}

bool HistoryDatabase::ContainsRecycleBin() const {
  return schema_version() >= 1.0 - kSchemaEpsilon && schema_revision() >= 2;
}

bool HistoryDatabase::CheckSchemaCompatibility() {
  return !((schema_version() < kLatestSupportedSchema - kSchemaEpsilon) ||
           (schema_version() > kLatestSchema          + kSchemaEpsilon));
}

bool HistoryDatabase::LiveSchemaUpgradeIfNecessary() {
  assert(read_write());
  assert(IsEqualSchema(schema_version(), 1.0));

  if (schema_revision() == kLatestSchemaRevision) {
    return true;
  }

  LogCvmfs(kLogHistory, kLogDebug, "upgrading history schema revision "
                                   "%.2f (Rev: %d) to %.2f (Rev: %d)",
           schema_version(), schema_revision(),
           kLatestSchema, kLatestSchemaRevision);

  const bool success = UpgradeSchemaRevision_10_1() &&
                       UpgradeSchemaRevision_10_2();

  return success && StoreSchemaRevision();
}

bool HistoryDatabase::UpgradeSchemaRevision_10_1() {
  if (schema_revision() > 0) {
    return true;
  }

  sqlite::Sql sql_upgrade(sqlite_db(), "ALTER TABLE tags ADD size INTEGER;");
  if (!sql_upgrade.Execute()) {
    LogCvmfs(kLogHistory, kLogStderr, "failed to upgrade tags table");
    return false;
  }

  set_schema_revision(1);
  return true;
}

bool HistoryDatabase::UpgradeSchemaRevision_10_2() {
  if (schema_revision() > 1) {
    return true;
  }

  if (!CreateRecycleBinTable()) {
    LogCvmfs(kLogHistory, kLogStderr, "failed to upgrade history database");
    return false;
  }

  set_schema_revision(2);
  return true;
}

//------------------------------------------------------------------------------

#define DB_FIELDS_V1R0  "name, hash, revision, timestamp, channel, description"
#define DB_FIELDS_V1R1  "name, hash, revision, timestamp, channel, " \
                        "description,  size"
#define DB_PLACEHOLDERS ":name, :hash, :revision, :timestamp, :channel, " \
                        ":description, :size"
#define ROLLBACK_COND   "(revision > :target_rev  OR " \
                        " name     = :target_name)   " \
                        "AND channel  = :target_chan "

#define MAKE_STATEMENT(STMT_TMPL, REV)       \
static const std::string REV =               \
  ReplaceAll(                                \
    ReplaceAll(                              \
      ReplaceAll(STMT_TMPL,                  \
        "@DB_FIELDS@", DB_FIELDS_ ## REV),   \
      "@DB_PLACEHOLDERS@", DB_PLACEHOLDERS), \
    "@ROLLBACK_COND@", ROLLBACK_COND)

#define MAKE_STATEMENTS(STMT_TMPL) \
  MAKE_STATEMENT(STMT_TMPL, V1R0); \
  MAKE_STATEMENT(STMT_TMPL, V1R1)

#define DEFERRED_INIT(DB, REV) \
  DeferredInit((DB)->sqlite_db(), (REV).c_str())

#define DEFERRED_INITS(DB) \
  if ((DB)->IsEqualSchema((DB)->schema_version(), 1.0f) && \
      (DB)->schema_revision() == 0) {                      \
    DEFERRED_INIT((DB), V1R0);                             \
  } else {                                                 \
    DEFERRED_INIT((DB), V1R1);                             \
  }

SqlInsertTag::SqlInsertTag(const HistoryDatabase *database) {
  MAKE_STATEMENTS("INSERT INTO tags (@DB_FIELDS@) VALUES (@DB_PLACEHOLDERS@);");
  DEFERRED_INITS(database);
}

bool SqlInsertTag::BindTag(const History::Tag &tag) {
  return
    BindText(1, tag.name) &&
    BindTextTransient(2, tag.root_hash.ToString()) &&  // temporary (ToString)
    BindInt64(3, tag.revision) &&
    BindInt64(4, tag.timestamp) &&
    BindInt64(5, tag.channel) &&
    BindText(6, tag.description) &&
    BindInt64(7, tag.size);
}

//------------------------------------------------------------------------------

SqlRemoveTag::SqlRemoveTag(const HistoryDatabase *database) {
  DeferredInit(database->sqlite_db(), "DELETE FROM tags WHERE name = :name;");
}

bool SqlRemoveTag::BindName(const std::string &name) {
  return BindText(1, name);
}

//------------------------------------------------------------------------------

SqlFindTag::SqlFindTag(const HistoryDatabase *database) {
  MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM tags WHERE name = :name LIMIT 1;");
  DEFERRED_INITS(database);
}

bool SqlFindTag::BindName(const std::string &name) {
  return BindText(1, name);
}

//------------------------------------------------------------------------------

SqlFindTagByDate::SqlFindTagByDate(const HistoryDatabase *database) {
  // figure out the tag that was HEAD to a given point in time
  //
  // conceptually goes back in the revision history  |  ORDER BY revision DESC
  // and picks the first tag                         |  LIMIT 1
  // that is older than the given timestamp          |  WHICH timestamp <= :ts
  MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM tags "
                  "WHERE timestamp <= :timestamp "
                  "ORDER BY revision DESC LIMIT 1;");
  DEFERRED_INITS(database);
}

bool SqlFindTagByDate::BindTimestamp(const time_t timestamp) {
  return BindInt64(1, timestamp);
}

//------------------------------------------------------------------------------

SqlCountTags::SqlCountTags(const HistoryDatabase *database) {
  DeferredInit(database->sqlite_db(), "SELECT count(*) FROM tags;");
}

unsigned SqlCountTags::RetrieveCount() const {
  int64_t count = RetrieveInt64(0);
  assert(count >= 0);
  return static_cast<uint64_t>(count);
}

//------------------------------------------------------------------------------

SqlListTags::SqlListTags(const HistoryDatabase *database) {
  MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM tags ORDER BY revision DESC;");
  DEFERRED_INITS(database);
}

//------------------------------------------------------------------------------

SqlGetChannelTips::SqlGetChannelTips(const HistoryDatabase *database) {
  MAKE_STATEMENTS("SELECT @DB_FIELDS@, MAX(revision) AS max_rev "
                  "FROM tags "
                  "GROUP BY channel;");
  DEFERRED_INITS(database);
}

SqlGetHashes::SqlGetHashes(const HistoryDatabase *database) {
  DeferredInit(database->sqlite_db(), "SELECT DISTINCT hash FROM tags "
                                      "ORDER BY revision ASC");
}

shash::Any SqlGetHashes::RetrieveHash() const {
  return shash::MkFromHexPtr(shash::HexPtr(RetrieveString(0)),
                             shash::kSuffixCatalog);
}

//------------------------------------------------------------------------------

SqlRollbackTag::SqlRollbackTag(const HistoryDatabase *database) {
  MAKE_STATEMENTS("DELETE FROM tags WHERE @ROLLBACK_COND@;");
  DEFERRED_INITS(database);
}

//------------------------------------------------------------------------------

SqlListRollbackTags::SqlListRollbackTags(const HistoryDatabase *database) {
  MAKE_STATEMENTS("SELECT @DB_FIELDS@ FROM tags "
                  "WHERE @ROLLBACK_COND@ "
                  "ORDER BY revision DESC;");
  DEFERRED_INITS(database);
}

//------------------------------------------------------------------------------

bool SqlRecycleBin::CheckSchema(const HistoryDatabase *database) const {
  return (database->IsEqualSchema(database->schema_version(), 1.0)) &&
         (database->schema_revision() >= 2);
}

//------------------------------------------------------------------------------

SqlRecycleBinInsert::SqlRecycleBinInsert(const HistoryDatabase *database) {
  assert(CheckSchema(database));
  DeferredInit(database->sqlite_db(),
               "INSERT OR IGNORE INTO recycle_bin (hash, flags) "
               "VALUES (:hash, :flags)");
}

bool SqlRecycleBinInsert::BindTag(const History::Tag &condemned_tag) {
  const unsigned int flags = SqlRecycleBin::kFlagCatalog;
  return
    BindTextTransient(1, condemned_tag.root_hash.ToString()) &&
    BindInt64(2, flags);
}

//------------------------------------------------------------------------------

SqlRecycleBinList::SqlRecycleBinList(const HistoryDatabase *database) {
  assert(CheckSchema(database));
  DeferredInit(database->sqlite_db(), "SELECT hash, flags FROM recycle_bin;");
}

shash::Any SqlRecycleBinList::RetrieveHash() {
  const unsigned int flags = RetrieveInt64(1);
  shash::Suffix suffix = shash::kSuffixNone;
  if (flags & SqlRecycleBin::kFlagCatalog) {
    suffix = shash::kSuffixCatalog;
  }

  return shash::MkFromHexPtr(shash::HexPtr(RetrieveString(0)), suffix);
}

//------------------------------------------------------------------------------

SqlRecycleBinFlush::SqlRecycleBinFlush(const HistoryDatabase *database) {
  assert(CheckSchema(database));
  DeferredInit(database->sqlite_db(), "DELETE FROM recycle_bin;");
}

//------------------------------------------------------------------------------

SqlRecycleBinRollback::SqlRecycleBinRollback(const HistoryDatabase *database) {
  assert(CheckSchema(database));
  const bool success = Init(database->sqlite_db(),
                            "INSERT OR IGNORE INTO recycle_bin (hash, flags) "
                            "SELECT hash, :flags "
                            "FROM tags WHERE " + rollback_condition + ";");
  assert(success);
}

bool SqlRecycleBinRollback::BindFlags() {
  return BindInt64(1, SqlRecycleBin::kFlagCatalog);
}

}; /* namespace history */
<|endoftext|>


<commit_before>/**
 * This file is part of the CernVM File System.
 */

#include "loader_talk.h"

#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>

#include <cstdlib>
#include <cassert>

#include "logging.h"
#include "util.h"
#include "loader.h"

using namespace std;  // NOLINT

namespace loader {
namespace loader_talk {

bool spawned_ = false;
string *socket_path_ = NULL;
int socket_fd_ = -1;
pthread_t thread_talk_;

bool Init(const string &socket_path) {
  spawned_ = false;
  socket_path_ = new string(socket_path);

  socket_fd_ = MakeSocket(*socket_path_, 0600);
  if (socket_fd_ == -1)
    return false;
  if (listen(socket_fd_, 1) == -1) {
    LogCvmfs(kLogCvmfs, kLogDebug, "listening on socket failed (%d)", errno);
    return false;
  }

  unlink((socket_path + ".paused.crashed").c_str());
  unlink((socket_path + ".paused").c_str());

  return true;
}

static void *MainTalk(void *data __attribute__((unused))) {
  struct sockaddr_un remote;
  socklen_t socket_size = sizeof(remote);
  int con_fd = -1;
  while (true) {
    if (con_fd > 0) {
      shutdown(con_fd, SHUT_RDWR);
      close(con_fd);
    }
    if ((con_fd = accept(socket_fd_, (struct sockaddr *)&remote, &socket_size))
         < 0)
    {
      break;
    }

    char command;
    if (recv(con_fd, &command, 1, 0) > 0) {
      if ((command != 'R') && (command != 'S')) {
        SendMsg2Socket(con_fd, "unknown command\n");
        continue;
      }

      SetLogMicroSyslog(*usyslog_path_);
      LogCvmfs(kLogCvmfs, kLogSyslog, "reloading Fuse module");
      int retval = Reload(con_fd, command == 'S');
      SendMsg2Socket(con_fd, "~");
      (void)send(con_fd, &retval, sizeof(retval), MSG_NOSIGNAL);
      if (retval != kFailOk) {
        LogCvmfs(kLogCvmfs, kLogSyslogErr, "reloading Fuse module failed "
                                           "(%d - %s)",
                 retval, Code2Ascii(static_cast<Failures>(retval)));
        abort();
      }
      SetLogMicroSyslog("");
    }
  }

  return NULL;
}

void Spawn() {
  int retval;
  retval = pthread_create(&thread_talk_, NULL, MainTalk, NULL);
  assert(retval == 0);
  spawned_ = true;
}

void Fini() {
  unlink(socket_path_->c_str());
  shutdown(socket_fd_, SHUT_RDWR);
  close(socket_fd_);
  if (spawned_) pthread_join(thread_talk_, NULL);

  delete socket_path_;
  socket_path_ = NULL;
  spawned_ = false;
  socket_fd_ = -1;
}

/**
 * Connects to a loader socket and triggers the reload
 */
int MainReload(const std::string &socket_path, const bool stop_and_go) {
  LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak,
           "Connecting to CernVM-FS loader... ");
  int socket_fd = ConnectSocket(socket_path);
  if (socket_fd < 0) {
    LogCvmfs(kLogCvmfs, kLogStdout, "failed!");
    return 100;
  }
  LogCvmfs(kLogCvmfs, kLogStdout, "done");

  const char command = stop_and_go ? 'S' : 'R';
  WritePipe(socket_fd, &command, 1);
  char buf;
  int retval;
  while ((retval = read(socket_fd, &buf, 1)) == 1) {
    if (buf == '~')
      break;
    LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "%c", buf);
  }
  if (retval != 1) {
    LogCvmfs(kLogCvmfs, kLogStderr, "Reload CRASHED! "
             "CernVM-FS mountpoints unusuable.");
    return 101;
  }

  int result = 102;
  read(socket_fd, &result, sizeof(result));
  if (result != kFailOk) {
    LogCvmfs(kLogCvmfs, kLogStderr, "Reload FAILED! "
             "CernVM-FS mountpoints unusuable.");
  }

  return result;
}

}  // namespace loader_talk
}  // namespace loader
<commit_msg>FIX: Coverity defect #56526<commit_after>/**
 * This file is part of the CernVM File System.
 */

#include "loader_talk.h"

#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>

#include <cstdlib>
#include <cassert>

#include "logging.h"
#include "util.h"
#include "loader.h"

using namespace std;  // NOLINT

namespace loader {
namespace loader_talk {

bool spawned_ = false;
string *socket_path_ = NULL;
int socket_fd_ = -1;
pthread_t thread_talk_;

bool Init(const string &socket_path) {
  spawned_ = false;
  socket_path_ = new string(socket_path);

  socket_fd_ = MakeSocket(*socket_path_, 0600);
  if (socket_fd_ == -1)
    return false;
  if (listen(socket_fd_, 1) == -1) {
    LogCvmfs(kLogCvmfs, kLogDebug, "listening on socket failed (%d)", errno);
    return false;
  }

  unlink((socket_path + ".paused.crashed").c_str());
  unlink((socket_path + ".paused").c_str());

  return true;
}

static void *MainTalk(void *data __attribute__((unused))) {
  struct sockaddr_un remote;
  socklen_t socket_size = sizeof(remote);
  int con_fd = -1;
  while (true) {
    if (con_fd >= 0) {
      shutdown(con_fd, SHUT_RDWR);
      close(con_fd);
    }
    if ((con_fd = accept(socket_fd_, (struct sockaddr *)&remote, &socket_size))
         < 0)
    {
      break;
    }

    char command;
    if (recv(con_fd, &command, 1, 0) > 0) {
      if ((command != 'R') && (command != 'S')) {
        SendMsg2Socket(con_fd, "unknown command\n");
        continue;
      }

      SetLogMicroSyslog(*usyslog_path_);
      LogCvmfs(kLogCvmfs, kLogSyslog, "reloading Fuse module");
      int retval = Reload(con_fd, command == 'S');
      SendMsg2Socket(con_fd, "~");
      (void)send(con_fd, &retval, sizeof(retval), MSG_NOSIGNAL);
      if (retval != kFailOk) {
        LogCvmfs(kLogCvmfs, kLogSyslogErr, "reloading Fuse module failed "
                                           "(%d - %s)",
                 retval, Code2Ascii(static_cast<Failures>(retval)));
        abort();
      }
      SetLogMicroSyslog("");
    }
  }

  return NULL;
}

void Spawn() {
  int retval;
  retval = pthread_create(&thread_talk_, NULL, MainTalk, NULL);
  assert(retval == 0);
  spawned_ = true;
}

void Fini() {
  unlink(socket_path_->c_str());
  shutdown(socket_fd_, SHUT_RDWR);
  close(socket_fd_);
  if (spawned_) pthread_join(thread_talk_, NULL);

  delete socket_path_;
  socket_path_ = NULL;
  spawned_ = false;
  socket_fd_ = -1;
}

/**
 * Connects to a loader socket and triggers the reload
 */
int MainReload(const std::string &socket_path, const bool stop_and_go) {
  LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak,
           "Connecting to CernVM-FS loader... ");
  int socket_fd = ConnectSocket(socket_path);
  if (socket_fd < 0) {
    LogCvmfs(kLogCvmfs, kLogStdout, "failed!");
    return 100;
  }
  LogCvmfs(kLogCvmfs, kLogStdout, "done");

  const char command = stop_and_go ? 'S' : 'R';
  WritePipe(socket_fd, &command, 1);
  char buf;
  int retval;
  while ((retval = read(socket_fd, &buf, 1)) == 1) {
    if (buf == '~')
      break;
    LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "%c", buf);
  }
  if (retval != 1) {
    LogCvmfs(kLogCvmfs, kLogStderr, "Reload CRASHED! "
             "CernVM-FS mountpoints unusuable.");
    return 101;
  }

  int result = 102;
  read(socket_fd, &result, sizeof(result));
  if (result != kFailOk) {
    LogCvmfs(kLogCvmfs, kLogStderr, "Reload FAILED! "
             "CernVM-FS mountpoints unusuable.");
  }

  return result;
}

}  // namespace loader_talk
}  // namespace loader
<|endoftext|>


<commit_before>// Copyright (C) 2022 by Pedro Mendes, Rector and Visitors of the
// University of Virginia, University of Heidelberg, and University
// of Connecticut School of Medicine.
// All rights reserved.

#include "catch.hpp"

extern std::string getTestFile(const std::string & fileName);

#include <copasi/CopasiTypes.h>
#include <sbml/SBMLTypes.h>
#include <sedml/SedTypes.h>

TEST_CASE("exporting sedml file with non-zero initial time", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  dm->newModel(NULL, true);

  auto * model = dm->getModel();

  auto * r = model->createReaction("R1");
  r->setReactionScheme("A -> B");

  model->setInitialTime(10.0);
  model->updateInitialValues(model->getInitialValueReference());

  auto & task = dynamic_cast<CTrajectoryTask&>((*dm->getTaskList())["Time-Course"]);
  task.setScheduled(true);
  auto * problem = dynamic_cast< CTrajectoryProblem * >(task.getProblem());
  REQUIRE(problem != nullptr);

  problem->setDuration(10);
  problem->setStepNumber(100);

  std::string sedml = dm->exportSEDMLToString(NULL, 1, 4);

  REQUIRE(sedml.find("<uniformTimeCourse id=\"sim1\" initialTime=\"10") != std::string::npos);

  // now lets try and read it back in ensuring that the initial time is being set.
  model->setInitialTime(0.0);
  model->updateInitialValues(model->getInitialValueReference());
  // also reset the task values, to see that hey are updated correctly
  problem->setDuration(1);
  problem->setStepNumber(10);

  auto * doc = readSedMLFromString(sedml.c_str());
  REQUIRE(doc->getNumErrors(LIBSEDML_SEV_ERROR) == 0);

  auto * sim = dynamic_cast<SedUniformTimeCourse*>(doc->getSimulation(0));
  REQUIRE(sim != nullptr);

  SEDMLImporter imp;
  imp.setDataModel(dm);
  imp.initializeContent();
  imp.setSEDMLDocument(doc);
  imp.setCopasiModel(model);
  imp.updateCopasiTaskForSimulation(sim, dm->getTaskList());

  REQUIRE(problem->getDuration() == 10);
  REQUIRE(problem->getStepNumber() == 100);

  delete doc;

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("convert sedml types and colors", "[copasi,sedml]")
{
  REQUIRE(SEDMLUtils::argbToRgba("112233") == "112233");
  REQUIRE(SEDMLUtils::argbToRgba("#F0C800") == "#F0C800");
  REQUIRE(SEDMLUtils::argbToRgba("#FFF0C800") == "#F0C800FF");
  REQUIRE(SEDMLUtils::argbToRgba("FFF0C800") == "#F0C800FF");
  REQUIRE(SEDMLUtils::argbToRgba("FFF0C800", false) == "F0C800FF");

  REQUIRE(SEDMLUtils::rgbaToArgb("112233") == "112233");
  REQUIRE(SEDMLUtils::rgbaToArgb("#F0C800") == "#F0C800");
  REQUIRE(SEDMLUtils::rgbaToArgb("#F0C800FF") == "#FFF0C800");
  REQUIRE(SEDMLUtils::rgbaToArgb("F0C800FF") == "#FFF0C800");
  REQUIRE(SEDMLUtils::rgbaToArgb("F0C800FF", false) == "FFF0C800");

  REQUIRE(SEDMLUtils::lineTypeFromSed(SEDML_LINETYPE_SOLID) == (int) CPlotItem::LineStyle::Solid);
  REQUIRE(SEDMLUtils::lineTypeFromSed(SEDML_LINETYPE_DASH) == (int) CPlotItem::LineStyle::Dashed);
  REQUIRE(SEDMLUtils::lineTypeFromSed(SEDML_LINETYPE_DOT) == (int) CPlotItem::LineStyle::Dotted);

  REQUIRE(SEDMLUtils::lineTypeToSed((int) CPlotItem::LineStyle::Solid) == SEDML_LINETYPE_SOLID);
  REQUIRE(SEDMLUtils::lineTypeToSed((int) CPlotItem::LineStyle::Dashed) == SEDML_LINETYPE_DASH);
  REQUIRE(SEDMLUtils::lineTypeToSed((int) CPlotItem::LineStyle::Dotted) == SEDML_LINETYPE_DOT);

  REQUIRE(SEDMLUtils::symbolFromSed(SEDML_MARKERTYPE_CIRCLE) == (int) CPlotItem::SymbolType::Circle);
  REQUIRE(SEDMLUtils::symbolFromSed(SEDML_MARKERTYPE_STAR) == (int) CPlotItem::SymbolType::Star);

  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::Circle) == SEDML_MARKERTYPE_CIRCLE);
  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::Star) == SEDML_MARKERTYPE_STAR);
  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::LargeCross) == SEDML_MARKERTYPE_PLUS);
  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::SmallCross) == SEDML_MARKERTYPE_PLUS);
  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::Plus) == SEDML_MARKERTYPE_PLUS);
}

TEST_CASE("importing new curves and plots", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(
    dm->importSEDML(
      getTestFile("test-data/test_shaded_area_overlap_order.sedml")
    ) == true);

  auto* plots = dm->getPlotDefinitionList();
  REQUIRE(plots->size() == 1);

  // test that we can export it again
  std::string sedml = dm->exportSEDMLToString(NULL, 1, 4);

  // export with sbml namespaces
  CSEDMLExporter exp;
  exp.setSBMLNamespaces(3, 1);
  std::string sedmlwith_ns =
    exp.exportModelAndTasksToString(*dm, "model.xml", 1, 4);

  REQUIRE(sedmlwith_ns.find("http://www.sbml.org/sbml/level3/version1/core") != std::string::npos);

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("importing variables with terms", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(dm->importSEDML(getTestFile("test-data/concentration_amount.sedml")) == true);

  auto * plots = dm->getPlotDefinitionList();
  REQUIRE(plots->size() == 3);

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("export nested scan", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(dm->loadModel(getTestFile("test-data/NestedScan.cps"), NULL) == true);

  auto sedml = dm->exportSEDMLToString(NULL, 1, 4);

  auto * doc = readSedMLFromString(sedml.c_str());

  REQUIRE(doc->getNumErrors(LIBSEDML_SEV_ERROR) == 0);

  REQUIRE(doc->getDataGenerator("Rtot_1_task3") == NULL);
  REQUIRE(doc->getDataGenerator("Rtot_1_task5") != NULL);

  delete doc;

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("Export different plot styles", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(dm->loadModel(getTestFile("test-data/brusselator.cps"), NULL) == true);

  auto * m = dm->getModel();
  REQUIRE(m != NULL);

  // export sbml so we have sbml ids
  std::string sbml = dm->exportSBMLToString(NULL, 3, 1);

  // export sedml
  std::string sedml = dm->exportSEDMLToString(NULL, 1, 4);

  auto * doc = readSedMLFromString(sedml.c_str());

  REQUIRE(doc->getNumErrors(LIBSEDML_SEV_ERROR) == 0);

  delete doc;

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("generating variables with terms", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(dm->loadModel(getTestFile("test-data/brusselator.cps"), NULL) == true);

  auto * m = dm->getModel();

  auto * pMV = m->createModelValue("g_mv", 1);

  // export to sbml so we have sbml ids for everything
  std::string sbml = dm->exportSBMLToString(NULL, 3, 1);

  {
    REQUIRE(VariableInfo(m).getSymbol() == SEDML_TIME_URN);
    REQUIRE(VariableInfo(m->getValueReference()).getSymbol() == SEDML_TIME_URN);
  }

  {
    REQUIRE(VariableInfo(&m->getCompartments()[0]).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfCompartments/sbml:compartment[@id='compartment']");
    REQUIRE(VariableInfo(m->getCompartments()[0].getRateReference()).getTerm() == SEDML_KISAO_RATE);
  }

  {
    REQUIRE(VariableInfo(&m->getMetabolites()[0]).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='X']");
    REQUIRE(VariableInfo(m->getMetabolites()[0].getConcentrationReference()).getTerm() == SEDML_KISAO_CONCENTRATION);
    REQUIRE(VariableInfo(m->getMetabolites()[0].getValueReference()).getTerm() == SEDML_KISAO_PARTICLENUMBER);
    REQUIRE(VariableInfo(m->getMetabolites()[0].getConcentrationRateReference()).getTerm() == SEDML_KISAO_CONCENTRATION_RATE);
    REQUIRE(VariableInfo(m->getMetabolites()[0].getRateReference()).getTerm() == SEDML_KISAO_PARTICLE_RATE);
  }

  {
    REQUIRE(VariableInfo(&m->getModelValues()[0]).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='g_mv']");
    REQUIRE(VariableInfo(m->getModelValues()[0].getRateReference()).getTerm() == SEDML_KISAO_RATE);
  }

  {
    REQUIRE(VariableInfo(&m->getReactions()[0]).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfReactions/sbml:reaction[@id='R1']");
    REQUIRE(VariableInfo(m->getReactions()[0].getFluxReference()).getTerm() == SEDML_KISAO_FLUX);
    REQUIRE(VariableInfo(m->getReactions()[0].getParameterObjects("k1").at(0)).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfReactions/sbml:reaction[@id='R1']/sbml:kineticLaw/sbml:listOfParameters/sbml:parameter[@id='k1']");
  }

  CRootContainer::removeDatamodel(dm);
}
<commit_msg>- issue 3093: test that '#' is added / removed consistently as requested<commit_after>// Copyright (C) 2021 - 2022 by Pedro Mendes, Rector and Visitors of the
// University of Virginia, University of Heidelberg, and University
// of Connecticut School of Medicine.
// All rights reserved.

#include "catch.hpp"

extern std::string getTestFile(const std::string & fileName);

#include <copasi/CopasiTypes.h>
#include <sbml/SBMLTypes.h>
#include <sedml/SedTypes.h>

TEST_CASE("exporting sedml file with non-zero initial time", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  dm->newModel(NULL, true);

  auto * model = dm->getModel();

  auto * r = model->createReaction("R1");
  r->setReactionScheme("A -> B");

  model->setInitialTime(10.0);
  model->updateInitialValues(model->getInitialValueReference());

  auto & task = dynamic_cast<CTrajectoryTask&>((*dm->getTaskList())["Time-Course"]);
  task.setScheduled(true);
  auto * problem = dynamic_cast< CTrajectoryProblem * >(task.getProblem());
  REQUIRE(problem != nullptr);

  problem->setDuration(10);
  problem->setStepNumber(100);

  std::string sedml = dm->exportSEDMLToString(NULL, 1, 4);

  REQUIRE(sedml.find("<uniformTimeCourse id=\"sim1\" initialTime=\"10") != std::string::npos);

  // now lets try and read it back in ensuring that the initial time is being set.
  model->setInitialTime(0.0);
  model->updateInitialValues(model->getInitialValueReference());
  // also reset the task values, to see that hey are updated correctly
  problem->setDuration(1);
  problem->setStepNumber(10);

  auto * doc = readSedMLFromString(sedml.c_str());
  REQUIRE(doc->getNumErrors(LIBSEDML_SEV_ERROR) == 0);

  auto * sim = dynamic_cast<SedUniformTimeCourse*>(doc->getSimulation(0));
  REQUIRE(sim != nullptr);

  SEDMLImporter imp;
  imp.setDataModel(dm);
  imp.initializeContent();
  imp.setSEDMLDocument(doc);
  imp.setCopasiModel(model);
  imp.updateCopasiTaskForSimulation(sim, dm->getTaskList());

  REQUIRE(problem->getDuration() == 10);
  REQUIRE(problem->getStepNumber() == 100);

  delete doc;

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("convert sedml types and colors", "[copasi,sedml]")
{
  REQUIRE(SEDMLUtils::argbToRgba("112233") == "#112233");
  REQUIRE(SEDMLUtils::argbToRgba("#F0C800") == "#F0C800");
  REQUIRE(SEDMLUtils::argbToRgba("#FFF0C800") == "#F0C800FF");
  REQUIRE(SEDMLUtils::argbToRgba("FFF0C800") == "#F0C800FF");
  REQUIRE(SEDMLUtils::argbToRgba("FFF0C800", false) == "F0C800FF");
  REQUIRE(SEDMLUtils::argbToRgba("#FF0000", false) == "FF0000");

  REQUIRE(SEDMLUtils::rgbaToArgb("112233") == "#112233");
  REQUIRE(SEDMLUtils::rgbaToArgb("#F0C800") == "#F0C800");
  REQUIRE(SEDMLUtils::rgbaToArgb("#F0C800FF") == "#FFF0C800");
  REQUIRE(SEDMLUtils::rgbaToArgb("F0C800FF") == "#FFF0C800");
  REQUIRE(SEDMLUtils::rgbaToArgb("F0C800FF", false) == "FFF0C800");
  REQUIRE(SEDMLUtils::rgbaToArgb("#FF0000", false) == "FF0000");

  REQUIRE(SEDMLUtils::lineTypeFromSed(SEDML_LINETYPE_SOLID) == (int) CPlotItem::LineStyle::Solid);
  REQUIRE(SEDMLUtils::lineTypeFromSed(SEDML_LINETYPE_DASH) == (int) CPlotItem::LineStyle::Dashed);
  REQUIRE(SEDMLUtils::lineTypeFromSed(SEDML_LINETYPE_DOT) == (int) CPlotItem::LineStyle::Dotted);

  REQUIRE(SEDMLUtils::lineTypeToSed((int) CPlotItem::LineStyle::Solid) == SEDML_LINETYPE_SOLID);
  REQUIRE(SEDMLUtils::lineTypeToSed((int) CPlotItem::LineStyle::Dashed) == SEDML_LINETYPE_DASH);
  REQUIRE(SEDMLUtils::lineTypeToSed((int) CPlotItem::LineStyle::Dotted) == SEDML_LINETYPE_DOT);

  REQUIRE(SEDMLUtils::symbolFromSed(SEDML_MARKERTYPE_CIRCLE) == (int) CPlotItem::SymbolType::Circle);
  REQUIRE(SEDMLUtils::symbolFromSed(SEDML_MARKERTYPE_STAR) == (int) CPlotItem::SymbolType::Star);

  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::Circle) == SEDML_MARKERTYPE_CIRCLE);
  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::Star) == SEDML_MARKERTYPE_STAR);
  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::LargeCross) == SEDML_MARKERTYPE_PLUS);
  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::SmallCross) == SEDML_MARKERTYPE_PLUS);
  REQUIRE(SEDMLUtils::symbolToSed((int) CPlotItem::SymbolType::Plus) == SEDML_MARKERTYPE_PLUS);
}

TEST_CASE("importing new curves and plots", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(
    dm->importSEDML(
      getTestFile("test-data/test_shaded_area_overlap_order.sedml")
    ) == true);

  auto* plots = dm->getPlotDefinitionList();
  REQUIRE(plots->size() == 1);

  // test that we can export it again
  std::string sedml = dm->exportSEDMLToString(NULL, 1, 4);

  // export with sbml namespaces
  CSEDMLExporter exp;
  exp.setSBMLNamespaces(3, 1);
  std::string sedmlwith_ns =
    exp.exportModelAndTasksToString(*dm, "model.xml", 1, 4);

  REQUIRE(sedmlwith_ns.find("http://www.sbml.org/sbml/level3/version1/core") != std::string::npos);

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("importing variables with terms", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(dm->importSEDML(getTestFile("test-data/concentration_amount.sedml")) == true);

  auto * plots = dm->getPlotDefinitionList();
  REQUIRE(plots->size() == 3);

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("export nested scan", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(dm->loadModel(getTestFile("test-data/NestedScan.cps"), NULL) == true);

  auto sedml = dm->exportSEDMLToString(NULL, 1, 4);

  auto * doc = readSedMLFromString(sedml.c_str());

  REQUIRE(doc->getNumErrors(LIBSEDML_SEV_ERROR) == 0);

  REQUIRE(doc->getDataGenerator("Rtot_1_task3") == NULL);
  REQUIRE(doc->getDataGenerator("Rtot_1_task5") != NULL);

  delete doc;

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("Export different plot styles", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(dm->loadModel(getTestFile("test-data/brusselator.cps"), NULL) == true);

  auto * m = dm->getModel();
  REQUIRE(m != NULL);

  // export sbml so we have sbml ids
  std::string sbml = dm->exportSBMLToString(NULL, 3, 1);

  // export sedml
  std::string sedml = dm->exportSEDMLToString(NULL, 1, 4);

  auto * doc = readSedMLFromString(sedml.c_str());

  REQUIRE(doc->getNumErrors(LIBSEDML_SEV_ERROR) == 0);

  delete doc;

  CRootContainer::removeDatamodel(dm);
}

TEST_CASE("generating variables with terms", "[copasi,sedml]")
{
  auto * dm = CRootContainer::addDatamodel();
  REQUIRE(dm != nullptr);

  REQUIRE(dm->loadModel(getTestFile("test-data/brusselator.cps"), NULL) == true);

  auto * m = dm->getModel();

  auto * pMV = m->createModelValue("g_mv", 1);

  // export to sbml so we have sbml ids for everything
  std::string sbml = dm->exportSBMLToString(NULL, 3, 1);

  {
    REQUIRE(VariableInfo(m).getSymbol() == SEDML_TIME_URN);
    REQUIRE(VariableInfo(m->getValueReference()).getSymbol() == SEDML_TIME_URN);
  }

  {
    REQUIRE(VariableInfo(&m->getCompartments()[0]).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfCompartments/sbml:compartment[@id='compartment']");
    REQUIRE(VariableInfo(m->getCompartments()[0].getRateReference()).getTerm() == SEDML_KISAO_RATE);
  }

  {
    REQUIRE(VariableInfo(&m->getMetabolites()[0]).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='X']");
    REQUIRE(VariableInfo(m->getMetabolites()[0].getConcentrationReference()).getTerm() == SEDML_KISAO_CONCENTRATION);
    REQUIRE(VariableInfo(m->getMetabolites()[0].getValueReference()).getTerm() == SEDML_KISAO_PARTICLENUMBER);
    REQUIRE(VariableInfo(m->getMetabolites()[0].getConcentrationRateReference()).getTerm() == SEDML_KISAO_CONCENTRATION_RATE);
    REQUIRE(VariableInfo(m->getMetabolites()[0].getRateReference()).getTerm() == SEDML_KISAO_PARTICLE_RATE);
  }

  {
    REQUIRE(VariableInfo(&m->getModelValues()[0]).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='g_mv']");
    REQUIRE(VariableInfo(m->getModelValues()[0].getRateReference()).getTerm() == SEDML_KISAO_RATE);
  }

  {
    REQUIRE(VariableInfo(&m->getReactions()[0]).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfReactions/sbml:reaction[@id='R1']");
    REQUIRE(VariableInfo(m->getReactions()[0].getFluxReference()).getTerm() == SEDML_KISAO_FLUX);
    REQUIRE(VariableInfo(m->getReactions()[0].getParameterObjects("k1").at(0)).getXpath() == "/sbml:sbml/sbml:model/sbml:listOfReactions/sbml:reaction[@id='R1']/sbml:kineticLaw/sbml:listOfParameters/sbml:parameter[@id='k1']");
  }

  CRootContainer::removeDatamodel(dm);
}
<|endoftext|>


<commit_before>//  (C) Copyright Gennadiy Rozental 2011-2014.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.

//[example_code
#define BOOST_TEST_MAIN
#include <boost/test/included/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/monomorphic.hpp>
#include <vector>
#include <map>

std::vector<int> generate_vector()
{
  std::vector<int> out;
  out.push_back(3);
  out.push_back(1);
  out.push_back(7);
  return out;
}

typedef const std::pair<const int, int> pair_int;
BOOST_TEST_DONT_PRINT_LOG_VALUE( pair_int );

const std::vector<int> v = generate_vector();
BOOST_DATA_TEST_CASE( test_case_1, data::make(v), var1)
{
  std::cout << var1 << std::endl;
  BOOST_CHECK(true);
}

std::map<int, int> generate_map()
{
  std::vector<int> v = generate_vector();
  std::map<int, int> out;
  for(std::size_t i = 0; i < v.size(); i++)
  {
    out[v[i]] = (i * 7) % 19;
  }
  return out;
}

const std::map<int, int> m = generate_map();
BOOST_DATA_TEST_CASE( test_case_2, data::make(m), var1)
{
  std::cout << var1->first << " -- " << var1->second << std::endl;
  BOOST_CHECK(true);
}
//]
<commit_msg>nothing<commit_after>//  (C) Copyright Gennadiy Rozental 2011-2014.
//  Distributed under the Boost Software License, Version 1.0.
//  (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org/libs/test for the library home page.

//[example_code
#define BOOST_TEST_MAIN
#include <boost/test/included/unit_test.hpp>
#include <boost/test/data/test_case.hpp>
#include <boost/test/data/monomorphic.hpp>
#include <vector>
#include <map>

namespace data = boost::unit_test::data;

std::vector<int> generate_vector()
{
  std::vector<int> out;
  out.push_back(3);
  out.push_back(1);
  out.push_back(7);
  return out;
}

typedef const std::pair<const int, int> pair_int;
BOOST_TEST_DONT_PRINT_LOG_VALUE( pair_int );

const std::vector<int> v = generate_vector();
BOOST_DATA_TEST_CASE( test_case_1, data::make(v), var1)
{
  std::cout << var1 << std::endl;
  BOOST_CHECK(true);
}

std::map<int, int> generate_map()
{
  std::vector<int> v = generate_vector();
  std::map<int, int> out;
  for(std::size_t i = 0; i < v.size(); i++)
  {
    out[v[i]] = (i * 7) % 19;
  }
  return out;
}

const std::map<int, int> m = generate_map();
BOOST_DATA_TEST_CASE( test_case_2, data::make(m), var1)
{
  std::cout << var1->first << " -- " << var1->second << std::endl;
  BOOST_CHECK(true);
}
//]
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Michael Egli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \author    Michael Egli
 * \copyright Michael Egli
 * \date      11-Jul-2015
 *
 * \file timer_test.cpp
 *
 * Tests for cpptime component. Compile with
 *
 * ~~~
 * g++ -g -std=c++11 -Wall -Wextra -o tests ../cpptime.cpp timer_test.cpp -l pthread
 * ~~~
 *
 */

#define CATCH_CONFIG_MAIN

// Includes
#include <thread>
#include <chrono>
#include "catch.hpp"
#include "../cpptime.h"

TEST_CASE("Test start and stop.")
{
	CppTime::start();
	CppTime::stop();
}

TEST_CASE("Tests with two argument add")
{
	CppTime::start();

	SECTION("Test uint64_t timeout argument")
	{
		int i = 0;
		CppTime::add(100000, [&](CppTime::timer_id) { i = 42; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 42);
	}

	SECTION("Test duration timeout argument")
	{
		int i = 0;
		CppTime::add(std::chrono::milliseconds(100), [&](CppTime::timer_id) { i = 43; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 43);
	}

	SECTION("Test time_point timeout argument")
	{
		int i = 0;
		CppTime::add(CppTime::clock::now() + std::chrono::milliseconds(100),
		    [&](CppTime::timer_id) { i = 44; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 44);
	}

	CppTime::stop();
}

TEST_CASE("Tests with three argument add")
{
	CppTime::start();

	SECTION("Test uint64_t timeout argument")
	{
		size_t count = 0;
		auto id = CppTime::add(100000, [&](CppTime::timer_id) { ++count; }, 10000);
		std::this_thread::sleep_for(std::chrono::milliseconds(125));
		CppTime::remove(id);
		REQUIRE(count == 3);
	}

	SECTION("Test duration timeout argument")
	{
		size_t count = 0;
		auto id = CppTime::add(std::chrono::milliseconds(100), [&](CppTime::timer_id) { ++count; },
		    std::chrono::microseconds(10000));
		std::this_thread::sleep_for(std::chrono::milliseconds(135));
		CppTime::remove(id);
		REQUIRE(count == 4);
	}

	CppTime::stop();
}

TEST_CASE("Test delete timer in callback")
{
	CppTime::start();

	size_t count = 0;
	auto id = CppTime::add(std::chrono::milliseconds(10), [&](CppTime::timer_id id) {
		++count;
		CppTime::remove(id);
	}, std::chrono::milliseconds(10));
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
	REQUIRE(count == 1);

	CppTime::stop();
}

TEST_CASE("Test two identical timeouts")
{
	int i = 0;
	int j = 0;
	CppTime::start();
	CppTime::timestamp t = CppTime::clock::now() + std::chrono::milliseconds(40);
	CppTime::add(t, [&](CppTime::timer_id) { i = 42; });
	CppTime::add(t, [&](CppTime::timer_id) { j = 43; });
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
	REQUIRE(i == 42);
	REQUIRE(j == 43);
	CppTime::stop();
}
<commit_msg>Add a test case with multiple timeouts to check the order of callbacks.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Michael Egli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \author    Michael Egli
 * \copyright Michael Egli
 * \date      11-Jul-2015
 *
 * \file timer_test.cpp
 *
 * Tests for cpptime component. Compile with
 *
 * ~~~
 * g++ -g -std=c++11 -Wall -Wextra -o tests ../cpptime.cpp timer_test.cpp -l pthread
 * ~~~
 *
 */

#define CATCH_CONFIG_MAIN

// Includes
#include <thread>
#include <chrono>
#include "catch.hpp"
#include "../cpptime.h"

TEST_CASE("Test start and stop.")
{
	CppTime::start();
	CppTime::stop();
}

TEST_CASE("Tests with two argument add")
{
	CppTime::start();

	SECTION("Test uint64_t timeout argument")
	{
		int i = 0;
		CppTime::add(100000, [&](CppTime::timer_id) { i = 42; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 42);
	}

	SECTION("Test duration timeout argument")
	{
		int i = 0;
		CppTime::add(std::chrono::milliseconds(100), [&](CppTime::timer_id) { i = 43; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 43);
	}

	SECTION("Test time_point timeout argument")
	{
		int i = 0;
		CppTime::add(CppTime::clock::now() + std::chrono::milliseconds(100),
		    [&](CppTime::timer_id) { i = 44; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 44);
	}

	CppTime::stop();
}

TEST_CASE("Tests with three argument add")
{
	CppTime::start();

	SECTION("Test uint64_t timeout argument")
	{
		size_t count = 0;
		auto id = CppTime::add(100000, [&](CppTime::timer_id) { ++count; }, 10000);
		std::this_thread::sleep_for(std::chrono::milliseconds(125));
		CppTime::remove(id);
		REQUIRE(count == 3);
	}

	SECTION("Test duration timeout argument")
	{
		size_t count = 0;
		auto id = CppTime::add(std::chrono::milliseconds(100), [&](CppTime::timer_id) { ++count; },
		    std::chrono::microseconds(10000));
		std::this_thread::sleep_for(std::chrono::milliseconds(135));
		CppTime::remove(id);
		REQUIRE(count == 4);
	}

	CppTime::stop();
}

TEST_CASE("Test delete timer in callback")
{
	CppTime::start();

	size_t count = 0;
	auto id = CppTime::add(std::chrono::milliseconds(10), [&](CppTime::timer_id id) {
		++count;
		CppTime::remove(id);
	}, std::chrono::milliseconds(10));
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
	REQUIRE(count == 1);

	CppTime::stop();
}

TEST_CASE("Test two identical timeouts")
{
	int i = 0;
	int j = 0;
	CppTime::start();
	CppTime::timestamp t = CppTime::clock::now() + std::chrono::milliseconds(40);
	CppTime::add(t, [&](CppTime::timer_id) { i = 42; });
	CppTime::add(t, [&](CppTime::timer_id) { j = 43; });
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
	REQUIRE(i == 42);
	REQUIRE(j == 43);
	CppTime::stop();
}

TEST_CASE("Test order of multiple timeouts")
{
	int i = 0;
	CppTime::start();
	CppTime::add(10000, [&](CppTime::timer_id) { i = 42; });
	CppTime::add(20000, [&](CppTime::timer_id) { i = 43; });
	CppTime::add(30000, [&](CppTime::timer_id) { i = 44; });
	CppTime::add(40000, [&](CppTime::timer_id) { i = 45; });
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
	REQUIRE(i == 45);
	CppTime::stop();
}
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Michael Egli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \author    Michael Egli
 * \copyright Michael Egli
 * \date      11-Jul-2015
 *
 * \file timer_test.cpp
 *
 * Tests for cpptime component. Compile with
 *
 * ~~~
 * g++ -g -std=c++11 -Wall -Wextra -o tests ../cpptime.cpp timer_test.cpp -l pthread
 * ~~~
 *
 */

#define CATCH_CONFIG_MAIN

// Includes
#include <thread>
#include <chrono>
#include "catch.hpp"
#include "../cpptime.h"

TEST_CASE("Test start and stop.")
{
	CppTime::start();
	CppTime::stop();
}

TEST_CASE("Tests with two argument add")
{
	CppTime::start();

	SECTION("Test uint64_t timeout argument")
	{
		int i = 0;
		CppTime::add(100000, [&](CppTime::timer_id) { i = 42; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 42);
	}

	SECTION("Test duration timeout argument")
	{
		int i = 0;
		CppTime::add(std::chrono::milliseconds(100), [&](CppTime::timer_id) { i = 43; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 43);
	}

	SECTION("Test time_point timeout argument")
	{
		int i = 0;
		CppTime::add(CppTime::clock::now() + std::chrono::milliseconds(100),
		    [&](CppTime::timer_id) { i = 44; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 44);
	}

	CppTime::stop();
}

TEST_CASE("Tests with three argument add")
{
	CppTime::start();

	SECTION("Test uint64_t timeout argument")
	{
		size_t count = 0;
		auto id = CppTime::add(100000, [&](CppTime::timer_id) { ++count; }, 10000);
		std::this_thread::sleep_for(std::chrono::milliseconds(125));
		CppTime::remove(id);
		REQUIRE(count == 3);
	}

	SECTION("Test duration timeout argument")
	{
		size_t count = 0;
		auto id = CppTime::add(std::chrono::milliseconds(100), [&](CppTime::timer_id) { ++count; },
		    std::chrono::microseconds(10000));
		std::this_thread::sleep_for(std::chrono::milliseconds(135));
		CppTime::remove(id);
		REQUIRE(count == 4);
	}

	CppTime::stop();
}

TEST_CASE("Test delete timer in callback")
{
	CppTime::start();

	size_t count = 0;
	auto id = CppTime::add(std::chrono::milliseconds(10), [&](CppTime::timer_id id) {
		++count;
		CppTime::remove(id);
	}, std::chrono::milliseconds(10));
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
	REQUIRE(count == 1);

	CppTime::stop();
}
<commit_msg>Add a test for two timers that fire at the exact same time.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Michael Egli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * \author    Michael Egli
 * \copyright Michael Egli
 * \date      11-Jul-2015
 *
 * \file timer_test.cpp
 *
 * Tests for cpptime component. Compile with
 *
 * ~~~
 * g++ -g -std=c++11 -Wall -Wextra -o tests ../cpptime.cpp timer_test.cpp -l pthread
 * ~~~
 *
 */

#define CATCH_CONFIG_MAIN

// Includes
#include <thread>
#include <chrono>
#include "catch.hpp"
#include "../cpptime.h"

TEST_CASE("Test start and stop.")
{
	CppTime::start();
	CppTime::stop();
}

TEST_CASE("Tests with two argument add")
{
	CppTime::start();

	SECTION("Test uint64_t timeout argument")
	{
		int i = 0;
		CppTime::add(100000, [&](CppTime::timer_id) { i = 42; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 42);
	}

	SECTION("Test duration timeout argument")
	{
		int i = 0;
		CppTime::add(std::chrono::milliseconds(100), [&](CppTime::timer_id) { i = 43; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 43);
	}

	SECTION("Test time_point timeout argument")
	{
		int i = 0;
		CppTime::add(CppTime::clock::now() + std::chrono::milliseconds(100),
		    [&](CppTime::timer_id) { i = 44; });
		std::this_thread::sleep_for(std::chrono::milliseconds(120));
		REQUIRE(i == 44);
	}

	CppTime::stop();
}

TEST_CASE("Tests with three argument add")
{
	CppTime::start();

	SECTION("Test uint64_t timeout argument")
	{
		size_t count = 0;
		auto id = CppTime::add(100000, [&](CppTime::timer_id) { ++count; }, 10000);
		std::this_thread::sleep_for(std::chrono::milliseconds(125));
		CppTime::remove(id);
		REQUIRE(count == 3);
	}

	SECTION("Test duration timeout argument")
	{
		size_t count = 0;
		auto id = CppTime::add(std::chrono::milliseconds(100), [&](CppTime::timer_id) { ++count; },
		    std::chrono::microseconds(10000));
		std::this_thread::sleep_for(std::chrono::milliseconds(135));
		CppTime::remove(id);
		REQUIRE(count == 4);
	}

	CppTime::stop();
}

TEST_CASE("Test delete timer in callback")
{
	CppTime::start();

	size_t count = 0;
	auto id = CppTime::add(std::chrono::milliseconds(10), [&](CppTime::timer_id id) {
		++count;
		CppTime::remove(id);
	}, std::chrono::milliseconds(10));
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
	REQUIRE(count == 1);

	CppTime::stop();
}

TEST_CASE("Test two identical timeouts")
{
	int i = 0;
	int j = 0;
	CppTime::start();
	CppTime::timestamp t = CppTime::clock::now() + std::chrono::milliseconds(40);
	CppTime::add(t, [&](CppTime::timer_id) { i = 42; });
	CppTime::add(t, [&](CppTime::timer_id) { j = 43; });
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
	REQUIRE(i == 42);
	REQUIRE(j == 43);
	CppTime::stop();
}
<|endoftext|>


<commit_before>/******************************************************************************
 Copyright 2019 Allied Telesis Labs Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice,
       this list of conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

#include "include/buildsys.h"

static bool directory_exists(const std::string &dir)
{
	if(!filesystem::exists(dir)) {
		/* Nothing here */
		return false;
	}
	if(buildsys::filesystem::is_directory(dir)) {
		/* Actually a directory */
		return true;
	}
	/* Something other than a directory */
	return false;
}

static bool refspec_is_commitid(const std::string &refspec)
{
	if(refspec.length() != 40) {
		return false;
	}

	for(char const &c : refspec) {
		if(isxdigit(c) == 0) {
			return false;
		}
	}

	return true;
}

static std::string git_hash_ref(const std::string &gdir, const std::string &refspec)
{
	std::string cmd = "cd " + gdir + " && git rev-parse " + refspec;
	FILE *f = popen(cmd.c_str(), "r");
	if(f == nullptr) {
		throw CustomException("git rev-parse ref failed");
	}
	char commit[41] = {};
	fread(commit, sizeof(char), 40, f);
	pclose(f);

	return std::string(commit);
}

static std::string git_hash(const std::string &gdir)
{
	return git_hash_ref(gdir, "HEAD");
}

static std::string git_diff_hash(const std::string &gdir)
{
	std::string cmd = "cd " + gdir + " && git diff HEAD | sha1sum";
	FILE *f = popen(cmd.c_str(), "r");
	if(f == nullptr) {
		throw CustomException("git diff | sha1sum failed");
	}
	char delta_hash[41] = {};
	fread(delta_hash, sizeof(char), 40, f);
	pclose(f);

	return std::string(delta_hash);
}

static std::string git_remote(const std::string &gdir, const std::string &remote)
{
	std::string cmd =
	    "cd " + gdir + " && git config --local --get remote." + remote + ".url";
	FILE *f = popen(cmd.c_str(), "r");
	if(f == nullptr) {
		throw CustomException("git config --local --get remote. .url failed");
	}
	char output[1025] = {};
	fread(output, sizeof(char), 1024, f);
	pclose(f);

	return std::string(output);
}

GitDirExtractionUnit::GitDirExtractionUnit(const std::string &git_dir,
                                           const std::string &to_dir)
{
	this->uri = git_dir;
	this->hash = git_hash(this->uri);
	this->toDir = to_dir;
}

bool GitDirExtractionUnit::isDirty()
{
	if(!directory_exists(this->localPath())) {
		/* If the source directory doesn't exist, then it can't be dirty */
		return false;
	}

	auto cmd = boost::format{"cd %1% && git diff --quiet HEAD"} % this->localPath();
	return (std::system(cmd.str().c_str()) != 0);
}

std::string GitDirExtractionUnit::dirtyHash()
{
	return git_diff_hash(this->localPath());
}

GitExtractionUnit::GitExtractionUnit(const std::string &remote, const std::string &_local,
                                     std::string _refspec, Package *_P)
{
	this->uri = remote;
	this->local = _P->getWorld()->getWorkingDir() + "/source/" + _local;
	this->refspec = std::move(_refspec);
	this->P = _P;
	this->fetched = false;
}

bool GitExtractionUnit::updateOrigin()
{
	std::string location = this->uri;
	std::string source_dir = this->local;
	std::string remote_url = git_remote(source_dir, "origin");

	if(remote_url != location) {
		PackageCmd pc(source_dir, "git");
		pc.addArg("remote");
		// If the remote doesn't exist, add it
		if(remote_url.empty()) {
			pc.addArg("add");
		} else {
			pc.addArg("set-url");
		}
		pc.addArg("origin");
		pc.addArg(location);
		if(!pc.Run(this->P)) {
			throw CustomException("Failed: git remote set-url origin");
		}

		pc = PackageCmd(source_dir, "git");
		pc.addArg("fetch");
		pc.addArg("origin");
		pc.addArg("--tags");
		if(!pc.Run(this->P)) {
			throw CustomException("Failed: git fetch origin --tags");
		}
	}

	return true;
}

bool GitExtractionUnit::fetch(BuildDir *d)
{
	std::string location = this->uri;
	std::string source_dir = this->local;
	std::string cwd = d->getWorld()->getWorkingDir();

	bool exists = directory_exists(source_dir);

	PackageCmd pc(exists ? source_dir : cwd, "git");

	if(exists) {
		/* Update the origin */
		this->updateOrigin();
		/* Check if the commit is already present */
		std::string cmd =
		    "cd " + source_dir + "; git cat-file -e " + this->refspec + " 2>/dev/null";
		if(std::system(cmd.c_str()) != 0) {
			/* If not, fetch everything from origin */
			pc.addArg("fetch");
			pc.addArg("origin");
			pc.addArg("--tags");
			if(!pc.Run(this->P)) {
				throw CustomException("Failed: git fetch origin --tags");
			}
		}
	} else {
		pc.addArg("clone");
		pc.addArg("-n");
		pc.addArg(location);
		pc.addArg(source_dir);
		if(!pc.Run(this->P)) {
			throw CustomException("Failed to git clone");
		}
	}

	if(this->refspec == "HEAD") {
		// Don't touch it
	} else {
		std::string cmd = "cd " + source_dir +
		                  "; git show-ref --quiet --verify -- refs/heads/" + this->refspec;
		if(std::system(cmd.c_str()) == 0) {
			std::string head_hash = git_hash_ref(source_dir, "HEAD");
			std::string branch_hash = git_hash_ref(source_dir, this->refspec);
			if(head_hash != branch_hash) {
				throw CustomException("Asked to use branch: " + this->refspec + ", but " +
				                      source_dir + " is off somewhere else");
			}
		} else {
			pc = PackageCmd(source_dir, "git");
			// switch to refspec
			pc.addArg("checkout");
			pc.addArg("-q");
			pc.addArg("--detach");
			pc.addArg(this->refspec);
			if(!pc.Run(this->P)) {
				throw CustomException("Failed to checkout");
			}
		}
	}
	bool res = true;

	std::string _hash = git_hash(source_dir);

	if(!this->hash.empty()) {
		if(this->hash != _hash) {
			log(this->P,
			    boost::format{"Hash mismatch for %1%\n(committed to %2%, providing %3%)"} %
			        this->uri % this->hash % _hash);
			res = false;
		}
	} else {
		this->hash = _hash;
	}

	this->fetched = res;

	return res;
}

std::string GitExtractionUnit::HASH()
{
	if(refspec_is_commitid(this->refspec)) {
		this->hash = this->refspec;
	} else {
		std::string digest_name = this->uri + "#" + this->refspec;
		/* Check if the package contains pre-computed hashes */
		std::string Hash = P->getFileHash(digest_name);
		if(Hash.empty()) {
			this->fetch(P->builddir());
		} else {
			this->hash = Hash;
		}
	}
	return this->hash;
}

bool GitExtractionUnit::extract(Package *_P)
{
	// make sure it has been fetched
	if(!this->fetched) {
		if(!this->fetch(_P->builddir())) {
			return false;
		}
	}
	// copy to work dir
	PackageCmd pc(_P->builddir()->getPath(), "cp");
	pc.addArg("-dpRuf");
	pc.addArg(this->localPath());
	pc.addArg(".");
	if(!pc.Run(_P)) {
		throw CustomException("Failed to checkout");
	}

	return true;
}

bool LinkGitDirExtractionUnit::extract(Package *P)
{
	PackageCmd pc(P->builddir()->getPath(), "ln");

	pc.addArg("-sfT");

	if(this->uri.at(0) == '.') {
		std::string arg = P->getWorld()->getWorkingDir() + "/" + this->uri;
		pc.addArg(arg);
	} else {
		pc.addArg(this->uri);
	}
	pc.addArg(this->toDir);

	if(!pc.Run(P)) {
		throw CustomException("Operation failed");
	}

	return true;
}

bool CopyGitDirExtractionUnit::extract(Package *P)
{
	PackageCmd pc(P->builddir()->getPath(), "cp");
	pc.addArg("-dpRuf");

	if(this->uri.at(0) == '.') {
		std::string arg = P->getWorld()->getWorkingDir() + "/" + this->uri;
		pc.addArg(arg);
	} else {
		pc.addArg(this->uri);
	}
	pc.addArg(this->toDir);

	if(!pc.Run(P)) {
		throw CustomException("Operation failed");
	}

	return true;
}
<commit_msg>extraction/git: Remove directory_exists function<commit_after>/******************************************************************************
 Copyright 2019 Allied Telesis Labs Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice,
       this list of conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

#include "include/buildsys.h"

static bool refspec_is_commitid(const std::string &refspec)
{
	if(refspec.length() != 40) {
		return false;
	}

	for(char const &c : refspec) {
		if(isxdigit(c) == 0) {
			return false;
		}
	}

	return true;
}

static std::string git_hash_ref(const std::string &gdir, const std::string &refspec)
{
	std::string cmd = "cd " + gdir + " && git rev-parse " + refspec;
	FILE *f = popen(cmd.c_str(), "r");
	if(f == nullptr) {
		throw CustomException("git rev-parse ref failed");
	}
	char commit[41] = {};
	fread(commit, sizeof(char), 40, f);
	pclose(f);

	return std::string(commit);
}

static std::string git_hash(const std::string &gdir)
{
	return git_hash_ref(gdir, "HEAD");
}

static std::string git_diff_hash(const std::string &gdir)
{
	std::string cmd = "cd " + gdir + " && git diff HEAD | sha1sum";
	FILE *f = popen(cmd.c_str(), "r");
	if(f == nullptr) {
		throw CustomException("git diff | sha1sum failed");
	}
	char delta_hash[41] = {};
	fread(delta_hash, sizeof(char), 40, f);
	pclose(f);

	return std::string(delta_hash);
}

static std::string git_remote(const std::string &gdir, const std::string &remote)
{
	std::string cmd =
	    "cd " + gdir + " && git config --local --get remote." + remote + ".url";
	FILE *f = popen(cmd.c_str(), "r");
	if(f == nullptr) {
		throw CustomException("git config --local --get remote. .url failed");
	}
	char output[1025] = {};
	fread(output, sizeof(char), 1024, f);
	pclose(f);

	return std::string(output);
}

GitDirExtractionUnit::GitDirExtractionUnit(const std::string &git_dir,
                                           const std::string &to_dir)
{
	this->uri = git_dir;
	this->hash = git_hash(this->uri);
	this->toDir = to_dir;
}

bool GitDirExtractionUnit::isDirty()
{
	if(!filesystem::is_directory(this->localPath())) {
		/* If the source directory doesn't exist, then it can't be dirty */
		return false;
	}

	auto cmd = boost::format{"cd %1% && git diff --quiet HEAD"} % this->localPath();
	return (std::system(cmd.str().c_str()) != 0);
}

std::string GitDirExtractionUnit::dirtyHash()
{
	return git_diff_hash(this->localPath());
}

GitExtractionUnit::GitExtractionUnit(const std::string &remote, const std::string &_local,
                                     std::string _refspec, Package *_P)
{
	this->uri = remote;
	this->local = _P->getWorld()->getWorkingDir() + "/source/" + _local;
	this->refspec = std::move(_refspec);
	this->P = _P;
	this->fetched = false;
}

bool GitExtractionUnit::updateOrigin()
{
	std::string location = this->uri;
	std::string source_dir = this->local;
	std::string remote_url = git_remote(source_dir, "origin");

	if(remote_url != location) {
		PackageCmd pc(source_dir, "git");
		pc.addArg("remote");
		// If the remote doesn't exist, add it
		if(remote_url.empty()) {
			pc.addArg("add");
		} else {
			pc.addArg("set-url");
		}
		pc.addArg("origin");
		pc.addArg(location);
		if(!pc.Run(this->P)) {
			throw CustomException("Failed: git remote set-url origin");
		}

		pc = PackageCmd(source_dir, "git");
		pc.addArg("fetch");
		pc.addArg("origin");
		pc.addArg("--tags");
		if(!pc.Run(this->P)) {
			throw CustomException("Failed: git fetch origin --tags");
		}
	}

	return true;
}

bool GitExtractionUnit::fetch(BuildDir *d)
{
	std::string location = this->uri;
	std::string source_dir = this->local;
	std::string cwd = d->getWorld()->getWorkingDir();

	bool exists = filesystem::is_directory(source_dir);

	PackageCmd pc(exists ? source_dir : cwd, "git");

	if(exists) {
		/* Update the origin */
		this->updateOrigin();
		/* Check if the commit is already present */
		std::string cmd =
		    "cd " + source_dir + "; git cat-file -e " + this->refspec + " 2>/dev/null";
		if(std::system(cmd.c_str()) != 0) {
			/* If not, fetch everything from origin */
			pc.addArg("fetch");
			pc.addArg("origin");
			pc.addArg("--tags");
			if(!pc.Run(this->P)) {
				throw CustomException("Failed: git fetch origin --tags");
			}
		}
	} else {
		pc.addArg("clone");
		pc.addArg("-n");
		pc.addArg(location);
		pc.addArg(source_dir);
		if(!pc.Run(this->P)) {
			throw CustomException("Failed to git clone");
		}
	}

	if(this->refspec == "HEAD") {
		// Don't touch it
	} else {
		std::string cmd = "cd " + source_dir +
		                  "; git show-ref --quiet --verify -- refs/heads/" + this->refspec;
		if(std::system(cmd.c_str()) == 0) {
			std::string head_hash = git_hash_ref(source_dir, "HEAD");
			std::string branch_hash = git_hash_ref(source_dir, this->refspec);
			if(head_hash != branch_hash) {
				throw CustomException("Asked to use branch: " + this->refspec + ", but " +
				                      source_dir + " is off somewhere else");
			}
		} else {
			pc = PackageCmd(source_dir, "git");
			// switch to refspec
			pc.addArg("checkout");
			pc.addArg("-q");
			pc.addArg("--detach");
			pc.addArg(this->refspec);
			if(!pc.Run(this->P)) {
				throw CustomException("Failed to checkout");
			}
		}
	}
	bool res = true;

	std::string _hash = git_hash(source_dir);

	if(!this->hash.empty()) {
		if(this->hash != _hash) {
			log(this->P,
			    boost::format{"Hash mismatch for %1%\n(committed to %2%, providing %3%)"} %
			        this->uri % this->hash % _hash);
			res = false;
		}
	} else {
		this->hash = _hash;
	}

	this->fetched = res;

	return res;
}

std::string GitExtractionUnit::HASH()
{
	if(refspec_is_commitid(this->refspec)) {
		this->hash = this->refspec;
	} else {
		std::string digest_name = this->uri + "#" + this->refspec;
		/* Check if the package contains pre-computed hashes */
		std::string Hash = P->getFileHash(digest_name);
		if(Hash.empty()) {
			this->fetch(P->builddir());
		} else {
			this->hash = Hash;
		}
	}
	return this->hash;
}

bool GitExtractionUnit::extract(Package *_P)
{
	// make sure it has been fetched
	if(!this->fetched) {
		if(!this->fetch(_P->builddir())) {
			return false;
		}
	}
	// copy to work dir
	PackageCmd pc(_P->builddir()->getPath(), "cp");
	pc.addArg("-dpRuf");
	pc.addArg(this->localPath());
	pc.addArg(".");
	if(!pc.Run(_P)) {
		throw CustomException("Failed to checkout");
	}

	return true;
}

bool LinkGitDirExtractionUnit::extract(Package *P)
{
	PackageCmd pc(P->builddir()->getPath(), "ln");

	pc.addArg("-sfT");

	if(this->uri.at(0) == '.') {
		std::string arg = P->getWorld()->getWorkingDir() + "/" + this->uri;
		pc.addArg(arg);
	} else {
		pc.addArg(this->uri);
	}
	pc.addArg(this->toDir);

	if(!pc.Run(P)) {
		throw CustomException("Operation failed");
	}

	return true;
}

bool CopyGitDirExtractionUnit::extract(Package *P)
{
	PackageCmd pc(P->builddir()->getPath(), "cp");
	pc.addArg("-dpRuf");

	if(this->uri.at(0) == '.') {
		std::string arg = P->getWorld()->getWorkingDir() + "/" + this->uri;
		pc.addArg(arg);
	} else {
		pc.addArg(this->uri);
	}
	pc.addArg(this->toDir);

	if(!pc.Run(P)) {
		throw CustomException("Operation failed");
	}

	return true;
}
<|endoftext|>


<commit_before>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrGLConfig.h"
#include "GrGLInterface.h"

void GrGLClearErr(const GrGLInterface* gl) {
    while (GR_GL_NO_ERROR != gl->fGetError()) {}
}

void GrGLCheckErr(const GrGLInterface* gl,
                  const char* location,
                  const char* call) {
    uint32_t err = GR_GL_GET_ERROR(gl);
    if (GR_GL_NO_ERROR != err) {
        GrPrintf("---- glGetError %x", GR_GL_GET_ERROR(gl));
        if (NULL != location) {
            GrPrintf(" at\n\t%s", location);
        }
        if (NULL != call) {
            GrPrintf("\n\t\t%s", call);
        }
        GrPrintf("\n");
    }
}

void GrGLResetRowLength(const GrGLInterface* gl) {
    if (gl->supportsDesktop()) {
        GR_GL_CALL(gl, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
    }
}

///////////////////////////////////////////////////////////////////////////////

#if GR_GL_LOG_CALLS
    bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
#endif

#if GR_GL_CHECK_ERROR
    bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
#endif

<commit_msg>Fix gl error debug print.<commit_after>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrGLConfig.h"
#include "GrGLInterface.h"

void GrGLClearErr(const GrGLInterface* gl) {
    while (GR_GL_NO_ERROR != gl->fGetError()) {}
}

void GrGLCheckErr(const GrGLInterface* gl,
                  const char* location,
                  const char* call) {
    uint32_t err = GR_GL_GET_ERROR(gl);
    if (GR_GL_NO_ERROR != err) {
        GrPrintf("---- glGetError %x", err);
        if (NULL != location) {
            GrPrintf(" at\n\t%s", location);
        }
        if (NULL != call) {
            GrPrintf("\n\t\t%s", call);
        }
        GrPrintf("\n");
    }
}

void GrGLResetRowLength(const GrGLInterface* gl) {
    if (gl->supportsDesktop()) {
        GR_GL_CALL(gl, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
    }
}

///////////////////////////////////////////////////////////////////////////////

#if GR_GL_LOG_CALLS
    bool gLogCallsGL = !!(GR_GL_LOG_CALLS_START);
#endif

#if GR_GL_CHECK_ERROR
    bool gCheckErrorGL = !!(GR_GL_CHECK_ERROR_START);
#endif

<|endoftext|>