Author: pmouawad
Date: Sat Apr 13 08:25:35 2019
New Revision: 1857453
URL: http://svn.apache.org/viewvc?rev=1857453&view=rev
Log:
Bug 63219 - New function "__StringToFile" to save a string into a file
Contributed by UbikLoadPack (https://ubikloadpack.com)
Bugzilla Id: 63219
Added:
jmeter/trunk/src/functions/org/apache/jmeter/functions/StringToFile.java (with props)
jmeter/trunk/test/src/org/apache/jmeter/functions/TestStringtoFile.java (with props)
Modified:
jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
jmeter/trunk/xdocs/changes.xml
jmeter/trunk/xdocs/usermanual/functions.xml
Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1857453&r1=1857452&r2=1857453&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Sat Apr 13 08:25:35
2019
@@ -1204,6 +1204,10 @@ string_from_file_encoding=File encoding
string_from_file_file_name=Enter path (absolute or relative) to file
string_from_file_seq_final=Final file sequence number (opt)
string_from_file_seq_start=Start file sequence number (opt)
+string_to_file_pathname=Path to file (absolute)
+string_to_file_content=String to write
+string_to_file_way_to_write=Append to file (true appends, false overwrites, default true)
+string_to_file_encoding=Charset (defaults to UTF-8)
summariser_title=Generate Summary Results
summary_report=Summary Report
switch_controller_label=Switch Value
Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1857453&r1=1857452&r2=1857453&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Sat Apr 13 08:25:35
2019
@@ -1193,6 +1193,10 @@ string_from_file_encoding=Encodage du fi
string_from_file_file_name=Entrer le chemin (absolu ou relatif) du fichier
string_from_file_seq_final=Nombre final de séquence de fichier
string_from_file_seq_start=Démarer le nombre de séquence de fichier
+string_to_file_pathname=Chemin du fichier (absolu)
+string_to_file_content=Chaîne de caractère à écrire
+string_to_file_way_to_write=Ajouter (true ajoute, false écrase, par défaut true)
+string_to_file_encoding=Encodage (UTF-8 par défaut)
summariser_title=Générer les resultats consolidés
summary_report=Rapport consolidé
switch_controller_label=Aller vers le numéro d'élément (ou nom) subordonné \:
Added: jmeter/trunk/src/functions/org/apache/jmeter/functions/StringToFile.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/functions/org/apache/jmeter/functions/StringToFile.java?rev=1857453&view=auto
==============================================================================
--- jmeter/trunk/src/functions/org/apache/jmeter/functions/StringToFile.java (added)
+++ jmeter/trunk/src/functions/org/apache/jmeter/functions/StringToFile.java Sat Apr 13 08:25:35
2019
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.jmeter.functions;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.StandardCharsets;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jmeter.engine.util.CompoundVariable;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.samplers.Sampler;
+import org.apache.jmeter.util.JMeterUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * FileToString Function to read a complete file into a String.
+ *
+ * Parameters:
+ * - file name
+ * - append (true/false)
+ * - file encoding (optional)
+ *
+ * Returns: true if ok , false if an error occured
+ *
+ * @since 5.2
+ */
+public class StringToFile extends AbstractFunction {
+ private static final Logger log = LoggerFactory.getLogger(StringToFile.class);
+ private static final List<String> desc = new LinkedList<>();
+ private static final String KEY = "__StringToFile";//$NON-NLS-1$
+ private static final ConcurrentHashMap<String, Lock> lockMap = new ConcurrentHashMap<>();
+ static {
+ desc.add(JMeterUtils.getResString("string_to_file_pathname"));
+ desc.add(JMeterUtils.getResString("string_to_file_content"));//$NON-NLS-1$
+ desc.add(JMeterUtils.getResString("string_to_file_way_to_write"));//$NON-NLS-1$
+ desc.add(JMeterUtils.getResString("string_to_file_encoding"));//$NON-NLS-1$
+ }
+ private Object[] values;
+
+ public StringToFile() {
+ super();
+ }
+
+ /**
+ * Write to file
+ * @return boolean true if success , false otherwise
+ * @throws IOException
+ */
+ private boolean writeToFile() throws IOException {
+ String fileName = ((CompoundVariable) values[0]).execute().trim();
+ String content = ((CompoundVariable) values[1]).execute();
+ boolean append = true;
+ if (values.length >= 3) {
+ append = Boolean.parseBoolean(((CompoundVariable) values[2]).execute().toLowerCase().trim());
+ }
+ Charset charset = StandardCharsets.UTF_8;
+ if (values.length == 4) {
+ String charsetParamValue = ((CompoundVariable) values[3]).execute();
+ if (StringUtils.isNotEmpty(charsetParamValue)) {
+ charset = Charset.forName(charsetParamValue);
+ }
+ }
+
+ if (fileName.isEmpty()) {
+ log.error("File name '{}' is empty", fileName);
+ return false;
+ }
+ log.debug("Writing {}Â to file {} with charset {} and append {}", content, fileName,
charset, append);
+
+ Lock localLock = new ReentrantLock();
+ Lock lock = lockMap.putIfAbsent(fileName, localLock);
+ try {
+ if (lock == null) {
+ localLock.lock();
+ } else {
+ lock.lock();
+ }
+ File file = new File(fileName);
+ File fileParent = file.getParentFile();
+ if (fileParent == null || (fileParent.exists() && fileParent.isDirectory()
&& fileParent.canWrite())) {
+ FileUtils.writeStringToFile(file, content, charset, append);
+ } else {
+ log.error("The parent file of {}Â doesn't exist or is not writable", file);
+ return false;
+ }
+ } finally {
+ if (lock == null) {
+ localLock.unlock();
+ } else {
+ lock.unlock();
+ }
+ }
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException
{
+ boolean executionResult;
+ try {
+ executionResult = this.writeToFile();
+ } catch (UnsupportedCharsetException ue) {
+ executionResult = false;
+ log.error("The encoding of file is not supported");
+ } catch (IllegalCharsetNameException ie) {
+ executionResult = false;
+ log.error("The encoding of file contains illegal characters");
+ } catch (IOException e) {
+ executionResult = false;
+ }
+ return String.valueOf(executionResult);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException
{
+ checkParameterCount(parameters, 2, 4);
+ values = parameters.toArray();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getReferenceKey() {
+ return KEY;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<String> getArgumentDesc() {
+ return desc;
+ }
+}
Propchange: jmeter/trunk/src/functions/org/apache/jmeter/functions/StringToFile.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/src/functions/org/apache/jmeter/functions/StringToFile.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: jmeter/trunk/test/src/org/apache/jmeter/functions/TestStringtoFile.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/test/src/org/apache/jmeter/functions/TestStringtoFile.java?rev=1857453&view=auto
==============================================================================
--- jmeter/trunk/test/src/org/apache/jmeter/functions/TestStringtoFile.java (added)
+++ jmeter/trunk/test/src/org/apache/jmeter/functions/TestStringtoFile.java Sat Apr 13 08:25:35
2019
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.jmeter.functions;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.jmeter.engine.util.CompoundVariable;
+import org.apache.jmeter.junit.JMeterTestCase;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.threads.JMeterContext;
+import org.apache.jmeter.threads.JMeterContextService;
+import org.apache.jmeter.threads.JMeterVariables;
+import org.apache.jmeter.util.JMeterUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tests for {@link StringToFile}
+ */
+public class TestStringtoFile extends JMeterTestCase {
+ protected AbstractFunction function;
+ private SampleResult result;
+ private Collection<CompoundVariable> params;
+ private static final Logger log = LoggerFactory.getLogger(TestSimpleFunctions.class);
+ private static final String DIR_NAME = "dirTest";
+ private static final String FILENAME = "test.txt";
+ private static final String STRING_TO_WRITE = "test";
+ private static final String ENCODING = StandardCharsets.UTF_8.toString();
+ @Rule
+ public TemporaryFolder tempFolder = new TemporaryFolder();
+
+ @Before
+ public void setUp() {
+ function = new StringToFile();
+ result = new SampleResult();
+ JMeterContext jmctx = JMeterContextService.getContext();
+ JMeterVariables vars = new JMeterVariables();
+ jmctx.setVariables(vars);
+ jmctx.setPreviousResult(result);
+ params = new LinkedList<>();
+ }
+
+ @Before
+ @After
+ public void deleteFileBeforeAfterTest() {
+ File file = new File(FILENAME);
+ try {
+ Files.deleteIfExists(file.toPath());
+ } catch (IOException e) {
+ Assert.fail("File " + FILENAME + "should not exist");
+ }
+ }
+
+ @Test
+ public void testParameterCount() throws Exception {
+ checkInvalidParameterCounts(function, 2, 4);
+ }
+
+ @Test
+ public void testWriteToFile() throws Exception {
+ params.add(new CompoundVariable(FILENAME));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable(ENCODING));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertTrue("This method 'Stringtofile' should have successfully run",
+ Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testWriteToFileWhenDirectoryDoesntExist() throws Exception {
+ String pathDirectory = File.separator + DIR_NAME;
+ File dir = new File(pathDirectory);
+ if (dir.exists()) {
+ deleteDir(dir);
+ }
+ String pathname = pathDirectory + File.separator + FILENAME;
+ params.add(new CompoundVariable(pathname));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable(ENCODING));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertFalse("This method 'Stringtofile' should fail to run since directory
does not exist",
+ Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testWriteToFileWhenDirectoryExist() throws InvalidVariableException {
+ File dir = null;
+ try {
+ dir = tempFolder.newFolder(DIR_NAME);
+ } catch (IOException e1) {
+ Assert.fail("can't create the directory");
+ }
+ String pathname = dir.getAbsolutePath() + File.separator + FILENAME;
+ params.add(new CompoundVariable(pathname));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable(ENCODING));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertTrue("This method 'Stringtofile' should have successfully run if parent
directory already exists",
+ Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testWriteToFileOptParamWayToWriteIsNull() throws Exception {
+ params.add(new CompoundVariable(FILENAME));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertTrue("This method 'Stringtofile' should have successfully run with empty
append",
+ Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testWriteToFileOptParamEncodingIsNull() throws Exception {
+ params.add(new CompoundVariable(FILENAME));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertTrue("This method 'Stringtofile' should have successfully run with no
charset",
+ Boolean.parseBoolean(returnValue));
+
+ }
+
+ @Test
+ public void testWriteToFileEncodingNotSupported() throws Exception {
+ File file = null;
+ try {
+ file = tempFolder.newFile(FILENAME);
+ } catch (IOException e1) {
+ Assert.fail("Can't create the file successfully");
+ }
+ params.add(new CompoundVariable(file.getAbsolutePath()));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable("UTF-20"));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertFalse("This method 'Stringtofile' should have failed to run with wrong
charset",
+ Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testWriteToFileEncodingNotLegal() throws Exception {
+ File file = null;
+ try {
+ file = tempFolder.newFile(FILENAME);
+ } catch (IOException e1) {
+ Assert.fail("Can't create the file successfully");
+ }
+ params.add(new CompoundVariable(file.getAbsolutePath()));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable("UTFéé"));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertFalse("This method 'Stringtofile' should have failed to run with illegal
chars in charset",
+ Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testWriteToFileIOException() throws Exception {
+ File file = null;
+ try {
+ file = tempFolder.newFile(FILENAME);
+ } catch (IOException e1) {
+ Assert.fail("Can't create the file successfully");
+ }
+ file.setWritable(false);
+ params.add(new CompoundVariable(file.getAbsolutePath()));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable("UTF-8"));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertFalse("This method 'Stringtofile' should have failed to run with non
writable folder",
+ Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testWriteToFileRequiredFilePathIsNull() throws Exception {
+ params.add(new CompoundVariable(null));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable(ENCODING));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertFalse("This method 'Stringtofile' should fail to run with null file",
Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testWriteToFileRequiredStringIsNull() throws Exception {
+ File file = null;
+ try {
+ file = tempFolder.newFile(FILENAME);
+ } catch (IOException e1) {
+ Assert.fail("Can't create the file successfully");
+ }
+ params.add(new CompoundVariable(file.getAbsolutePath()));
+ params.add(new CompoundVariable(""));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable(ENCODING));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertTrue("This method 'Stringtofile' should succeed with empty String to
write",
+ Boolean.parseBoolean(returnValue));
+ }
+
+ @Test
+ public void testOverwrite() throws Exception {
+ File file = null;
+ try {
+ file = tempFolder.newFile(FILENAME);
+ } catch (IOException e1) {
+ Assert.fail("Can't create the file successfully");
+ }
+ params.add(new CompoundVariable(file.getAbsolutePath()));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("false"));
+ params.add(new CompoundVariable(ENCODING));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ Assert.assertTrue("This method 'Stringtofile' should have successfully run",
+ Boolean.parseBoolean(returnValue));
+ String res = FileUtils.readFileToString(file, ENCODING).trim();
+ Assert.assertEquals("The string should be 'test'", "test", res);
+ }
+
+ @Test
+ public void testAppend() throws Exception {
+ File file = null;
+ try {
+ file = tempFolder.newFile(FILENAME);
+ } catch (IOException e1) {
+ Assert.fail("Can't create the file successfully");
+ }
+ params.add(new CompoundVariable(file.getAbsolutePath()));
+ params.add(new CompoundVariable(STRING_TO_WRITE));
+ params.add(new CompoundVariable("true"));
+ params.add(new CompoundVariable(ENCODING));
+ function.setParameters(params);
+ String returnValue = function.execute(result, null);
+ returnValue = function.execute(result, null);
+ Assert.assertTrue("This method 'Stringtofile' should have successfully run",
+ Boolean.parseBoolean(returnValue));
+ String res = FileUtils.readFileToString(file, ENCODING).trim();
+ Assert.assertEquals("The string should be 'testtest'", "testtest", res);
+ }
+
+ @Test
+ public void testDescription() {
+ Assert.assertEquals("Function 'stringtofile' should have successfully reading the
configuration file 'messages.properties'",
+ JMeterUtils.getResString("string_to_file_pathname"),
+ function.getArgumentDesc().get(0));
+ }
+
+ private static boolean deleteDir(File dir) {
+ if (dir.isDirectory()) {
+ String[] children = dir.list();
+ for (int i = 0; i < children.length; i++) {
+ boolean success = deleteDir(new File(dir, children[i]));
+ if (!success) {
+ return false;
+ }
+ }
+ }
+ try {
+ Files.deleteIfExists(dir.toPath());
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+}
Propchange: jmeter/trunk/test/src/org/apache/jmeter/functions/TestStringtoFile.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jmeter/trunk/test/src/org/apache/jmeter/functions/TestStringtoFile.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1857453&r1=1857452&r2=1857453&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Sat Apr 13 08:25:35 2019
@@ -102,6 +102,7 @@ to view the last major behaviors with th
<h3>Functions</h3>
<ul>
+ <li><bug>63219</bug>New function <code>__StringToFile</code>
to save a string into a file. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
</ul>
<h3>I18N</h3>
@@ -173,6 +174,7 @@ to view the last major behaviors with th
</p>
<ul>
<li>Clifford Harms (clifford.harms at gmail.com)</li>
+ <li><a href="https://ubikloadpack.com">Ubik Load Pack</a></li>
</ul>
<p>We also thank bug reporters who helped us improve JMeter.</p>
<ul>
Modified: jmeter/trunk/xdocs/usermanual/functions.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/functions.xml?rev=1857453&r1=1857452&r2=1857453&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/functions.xml (original)
+++ jmeter/trunk/xdocs/usermanual/functions.xml Sat Apr 13 08:25:35 2019
@@ -120,6 +120,7 @@ Alternatively, just use <code>/</code> i
<tr><td>Input</td><td> <a href="#__FileToString">FileToString</a></td><td>read
an entire file</td><td>2.4</td></tr>
<tr><td>Input</td><td> <a href="#__CSVRead">CSVRead</a></td><td>read
from CSV delimited file</td><td>1.9</td></tr>
<tr><td>Input</td><td> <a href="#__XPath">XPath</a></td><td>Use
an XPath expression to read from a file</td><td>2.0.3</td></tr>
+ <tr><td>Input</td><td> <a href="#__StringToFile">StringToFile</a></td><td>write
a string to a file</td><td>5.2</td></tr>
<tr><td>Calculation</td><td> <a href="#__counter">counter</a></td><td>generate
an incrementing number</td><td>1.X</td></tr>
<tr><td>Formatting</td><td> <a href="#__dateTimeConvert">dateTimeConvert</a></td><td>Convert
a date or time from source to target format</td><td>4.0</td></tr>
<tr><td>Calculation</td><td> <a href="#__digest">digest</a></td><td>Generate
a digest (SHA-1, SHA-256, MD5...)</td><td>4.0</td></tr>
@@ -1483,7 +1484,6 @@ A reference name - <code>refName</code>
</properties>
<p>The file name, encoding and reference name parameters are resolved every time the
function is executed.</p>
</component>
-
<component index="§-num;.5.30" name="__samplerName">
<description>
@@ -1712,6 +1712,30 @@ returns:
</p>
</component>
+<component index="§-num;.5.39" name="__StringToFile">
+<description>
+ <p>
+ The <code>__StringToFile</code> function can be used to write a string to
a file.
+ Each time it is called it writes a string to file appending or overwriting.
+ </p>
+ <p>The default return value from the function is the empty string</p>
+</description>
+<properties>
+ <property name="Path to file" required="Yes">
+ Path to the file name.(The path is absolute)
+ </property>
+ <property name="String to write" required="Yes">
+ The string to write to the file
+ </property>
+ <property name="File encoding if not UTF-8" required="No">
+ The encoding to be used to write to the file. If not specified, the default encoding
is <code>UTF-8</code>.
+ </property>
+ <property name="Append to file?" required="No">
+ The way to write the string, <code>true</code> means append, <code>false</code>
means overwrite.
+ </property>
+</properties>
+</component>
+
</subsection>
<subsection name="§-num;.6 Pre-defined Variables" anchor="predefinedvars">
|