def METHOD_NAME(self, data, rate, ssize, nchannels):
    try:
        dsp = ossaudiodev.open('w')
    except OSError as msg:
        if msg.args[0] in (errno.EACCES, errno.ENOENT,
                           errno.ENODEV, errno.EBUSY):
            raise unittest.SkipTest(msg)
        raise
    # at least check that these methods can be invoked
    dsp.bufsize()
    dsp.obufcount()
    dsp.obuffree()
    dsp.getptr()
    dsp.fileno()
    # Make sure the read-only attributes work.
    self.assertFalse(dsp.closed)
    self.assertEqual(dsp.name, "/dev/dsp")
    self.assertEqual(dsp.mode, "w", "bad dsp.mode: %r" % dsp.mode)
    # And make sure they're really read-only.
    for attr in ('closed', 'name', 'mode'):
        try:
            setattr(dsp, attr, 42)
        except (TypeError, AttributeError):
            pass
        else:
            self.fail("dsp.%s not read-only" % attr)
    # Compute expected running time of sound sample (in seconds).
    expected_time = float(len(data)) / (ssize/8) / nchannels / rate
    # set parameters based on .au file headers
    dsp.setparameters(AFMT_S16_NE, nchannels, rate)
    self.assertTrue(abs(expected_time - 3.51) < 1e-2, expected_time)
    t1 = time.monotonic()
    dsp.write(data)
    dsp.close()
    t2 = time.monotonic()
    elapsed_time = t2 - t1
    percent_diff = (abs(elapsed_time - expected_time) / expected_time) * 100
    self.assertTrue(percent_diff <= 10.0,
                    "elapsed time (%s) > 10%% off of expected time (%s)" %
                    (elapsed_time, expected_time))