1
\$\begingroup\$
private static byte[] GenerateData(long size)
{
    var result = new byte[size];
    new Random().NextBytes(result);

    return result;
}

Is it good, robust and efficient solution?

I use my method like this

[TestMethod]
public void WriteAndRead16MBbyZeroOffsetTest()
{
     var length = 1024 * 1024 * 16; // 16mb
     WriteAndReadTest(length);
}

private void WriteAndReadTest(long length, long offset = 0L)
{
    byte[] generatedData = GenerateData(length);
    byte[] expectedData = null;

    StorageException resultException = null;
    try
    {
         _blobReaderWriterLazy.Value.Write(offset, generatedData);
         _blobReaderWriterLazy.Value.Read(offset, length, out expectedData);
    }
    catch (StorageException exception)
    {
        resultException = exception;
    }

    Assert.IsNull(resultException);
    Assert.IsTrue(generatedData.Length == expectedData.Length);
    Assert.IsTrue(generatedData.SequenceEqual(expectedData));
}
\$\endgroup\$
6
  • 1
    \$\begingroup\$ For what purpose? A card game has different random number requirements than an initialization vector for an encryption algorithm, for example. \$\endgroup\$ Commented Apr 26, 2016 at 16:01
  • \$\begingroup\$ See: stackoverflow.com/a/2706537/2655508 \$\endgroup\$ Commented Apr 26, 2016 at 16:06
  • \$\begingroup\$ @JesseC.Slicer This array must represent a file with a particular size \$\endgroup\$ Commented Apr 26, 2016 at 16:08
  • \$\begingroup\$ @Anatoly ok, so down to the next level: What does the file represent? Is the random data for use in the future? Or is it throwaway? Or is it supposed to overwrite unused areas of a hard drive securely? \$\endgroup\$ Commented Apr 26, 2016 at 16:13
  • 1
    \$\begingroup\$ Yes, it is throwaway. I will use this method inside my tests class \$\endgroup\$ Commented Apr 26, 2016 at 16:17

2 Answers 2

7
\$\begingroup\$

I will use this method inside my tests class

Your plan is to generate random data to test your thing. Suppose a test fails. How are you planning on debugging it with the data that caused it to fail?

Don't randomize tests. Generate the random test data once, and save it, and then use it over and over again.

\$\endgroup\$
4
  • \$\begingroup\$ Great idea, thanks. Generate the random test data once, and save it. I don't understand how to do this, can you explain please? \$\endgroup\$ Commented Apr 27, 2016 at 5:24
  • \$\begingroup\$ I'm using C# and NUnit. I have a 10 unit tests. Previously I decided to call my GenerateData(specific_for_a_test) inside each of tests, but with different size (1MB, 100MB, 1GB). So how can I use your recommendation in my case? Can you provide a code please \$\endgroup\$ Commented Apr 27, 2016 at 5:51
  • \$\begingroup\$ I update my answer, and provide more code \$\endgroup\$ Commented Apr 27, 2016 at 6:02
  • 1
    \$\begingroup\$ @Anatoly You can use a PRNG together with a seed so that you will get the same test data each time your test is run. Note that "Random objects in processes running under different versions of the .NET Framework may return different series of random numbers even if they're instantiated with identical seed values", so you should keep that in mind (and consider using a different PRNG). \$\endgroup\$ Commented Apr 27, 2016 at 8:01
6
\$\begingroup\$

You don't need to new up a new random number generator every time. In fact, doing so may result in the same sequence of "random" numbers being generated if they're called too fast in succession (it bases itself off of ticks of the real-time clock). However, with a single instance of the RNG, you wind up with a similar issue as it's not thread-safe, so a mutual exclusion scheme needs to be used to keep its calls serialized. So, in the snippet below, there's one RNG created at the class level and then the lock keyword is used to ensure mutual exclusion from multiple threads.

private static readonly Random _Random = new Random();

private static byte[] GenerateData(long size)
{
    var result = new byte[size];

    lock (_Random)
    {
        _Random.NextBytes(result);
    }

    return result;
}
\$\endgroup\$
4
  • \$\begingroup\$ Maybe GenerateData() doesn't need to be static? In that case, you wouldn't need the lock. \$\endgroup\$ Commented May 1, 2016 at 1:13
  • \$\begingroup\$ I'm pretty sure its staticness doesn't determine whether or not it needs the lock - it's possible simultaneous access to the PRNG. Could be multiple readers in a non-static instance. \$\endgroup\$ Commented May 1, 2016 at 1:17
  • \$\begingroup\$ static methods almost always have to be thread-safe, instance methods usually don't (since each thread can have its own instance). \$\endgroup\$ Commented May 1, 2016 at 1:18
  • \$\begingroup\$ Can, yes. But it has to be designed as such. Perhaps it's time to link to Jon Skeet's Random helper: codeblog.jonskeet.uk/2009/11/04/revisiting-randomness \$\endgroup\$ Commented May 1, 2016 at 1:21

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.