FOSSology  4.4.0
Open Source License Compliance by Open Source Software
TestDbFactory.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014-2015 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
9 {
10 
11  public function setupTestDb($dbName=NULL)
12  {
13  date_default_timezone_set("UTC");
14  if (!is_callable('pg_connect'))
15  {
16  throw new \Exception("php-psql not found");
17  }
18  $sub = chr(mt_rand(97, 122)) . chr(mt_rand(97, 122)) . chr(mt_rand(97, 122)) . chr(mt_rand(97, 122));
19  if (empty($dbName))
20  {
21  $dbName = "fosstestone";
22  } else {
23  if ($dbName === "fossology") {
24  throw new \Exception("cannot use production database for tests");
25  }
26  }
27  $dbName = strtolower($dbName);
28  $this->ensurePgPassFileEntry();
29 
30  $sys_conf = sys_get_temp_dir() . "/$dbName" . time() . $sub;
31  if (!mkdir($sys_conf, $mode = 0755))
32  {
33  throw new \Exception("FATAL! Cannot create test repository at " . $sys_conf);
34  }
35  if (chmod($sys_conf, 0755) === FALSE)
36  {
37  throw new \Exception("ERROR: Cannot set mode to 755 on " . $sys_conf . "\n" . __FILE__ . " at line " . __LINE__ . "\n");
38  }
39  $conf = "dbname=$dbName;\nhost=localhost;\nuser=fossy;\npassword=fossy;\n";
40  if (file_put_contents($sys_conf . "/Db.conf", $conf) === FALSE)
41  {
42  throw new \Exception("FATAL! Could not create Db.conf file at " . $sys_conf);
43  }
44 
45  exec($cmd = "psql -Ufossy -h localhost -lqtA | cut -f 1 -d '|' | grep -q '^$dbName\$'", $cmdOut, $cmdRtn);
46  if ($cmdRtn == 0)
47  {
48  exec($cmd = "echo 'SELECT * FROM pg_language;' | psql -Ufossy -h localhost -t $dbName | grep -q plpgsql", $cmdOut, $cmdRtn);
49  if ($cmdRtn != 0)
50  {
51  exec($cmd = "echo 'CREATE LANGUAGE plpgsql;' | psql -Ufossy -h localhost $dbName", $cmdOut, $cmdRtn);
52  if ($cmdRtn != 0)
53  throw new \Exception("ERROR: failed to add plpgsql to $dbName database");
54  }
55  exec($cmd = "echo 'SELECT * FROM pg_extension;' | psql -Ufossy -h localhost -t $dbName | grep -q uuid-ossp", $cmdOut, $cmdRtn);
56  if ($cmdRtn != 0)
57  {
58  exec($cmd = "echo 'CREATE EXTENSION \"uuid-ossp\";' | psql -Ufossy -h localhost $dbName", $cmdOut, $cmdRtn);
59  if ($cmdRtn != 0)
60  throw new \Exception("ERROR: failed to add 'uuid-ossp' to $dbName database");
61  }
62  } else
63  {
64  $fosstestSql = file_get_contents(dirname(__FILE__) . '/../../lib/php/Test/fosstestinit.sql');
65  $fossSql = str_replace('fosstest', $dbName, $fosstestSql);
66  $pathSql = $sys_conf . '/dbinit.sql';
67  file_put_contents($pathSql, $fossSql);
68  exec($cmd = "psql -Ufossy -h localhost fossology < $pathSql", $cmdOut, $cmdRtn); // 2>&1
69  if ($cmdRtn != 0)
70  {
71  throw new \Exception("ERROR: Database failed during configuration.");
72  }
73  unlink($pathSql);
74  }
75 
76  return $sys_conf;
77  }
78 
79  private function ensurePgPassFileEntry()
80  {
81  $userHome = getenv('HOME');
82  $ipv4 = gethostbyname(gethostname());
83 
84  $contents = "localhost:*:*:fossy:fossy\n";
85  $pgpass = "$userHome/.pgpass";
86  putenv("PGPASSFILE=$pgpass");
87  $pg_pass_contents = file_exists($pgpass) ? file_get_contents($pgpass) : '';
88  if (!preg_match('/\:fossy\:fossy/', $pg_pass_contents))
89  {
90  $pgpassHandle = fopen($pgpass, 'w');
91  $howmany = fwrite($pgpassHandle, $contents);
92  if ($howmany === FALSE)
93  {
94  throw new \Exception("FATAL! Could not write .pgpass file to $pgpassHandle");
95  }
96  fclose($pgpassHandle);
97  }
98  if (!chmod($pgpass, 0600))
99  {
100  throw new \Exception("Warning! could not set $pgpass to 0600\n");
101  }
102  }
103 
104  public function getDbName($sys_conf)
105  {
106  $dbConfig = file_get_contents("$sys_conf/Db.conf");
107  if (!preg_match("/dbname=([[:alnum:]]+);.*/", $dbConfig, $matches))
108  {
109  throw new \Exception("could not parse db name");
110  }
111  return $matches[1];
112  }
113 
114  public function purgeTestDb($sys_conf=null)
115  {
116  if (empty($sys_conf)) {
117  $sys_conf = getenv('SYSCONFDIR');
118  }
119  if (empty($sys_conf)) {
120  throw new \Exception( "refusing to purge from /");
121  }
122 
123  $dbName = $this->getDbName($sys_conf);
124  if (empty($dbName)) {
125  throw new \Exception( "cannot determine db to empty");
126  }
127 
128  $existCmd = "psql -Ufossy -h localhost -l | grep -q " . $dbName;
129  exec($existCmd, $existkOut, $existRtn);
130  if ($existRtn != 0)
131  {
132  echo "NOTE: database " . $dbName . " does not exist, nothing to delete\n";
133  } else
134  {
135  $dropCmd = "dropdb -Ufossy -h localhost " . $dbName;
136  exec($dropCmd, $dropOut, $dropRtn);
137  if ($dropRtn != 0)
138  {
139  throw new \Exception("failed to delete database " . $dbName);
140  }
141  }
142  foreach (glob($sys_conf . "/*.*") as $filename)
143  {
144  unlink($filename);
145  }
146  exec("rm -rf $sys_conf");
147  }
148 }