def run()

in flexsai/p4/backend/json_stage/bmv2stf.py [0:0]


    def run(self):
        if self.options.verbose:
            print("Running model")
        wait = 0  # Time to wait before model starts running

        concurrent = ConcurrentInteger(os.getcwd(), 1000)
        rand = concurrent.generate()
        if rand is None:
            reportError("Could not find a free port for Thrift")
            return FAILURE
        thriftPort = str(9090 + rand)
        rv = SUCCESS
        try:
            os.remove("/tmp/bmv2-%d-notifications.ipc" % rand)
        except OSError:
            pass
        try:
            runswitch = [FindExe("behavioral-model", "simple_switch"),
                         "--log-file", self.switchLogFile, "--log-flush",
                         "--use-files", str(wait), "--thrift-port", thriftPort,
                         "--device-id", str(rand)] + self.interfaceArgs() + ["../" + self.jsonfile]
            if self.options.verbose:
                print("Running", " ".join(runswitch))
            sw = subprocess.Popen(runswitch, cwd=self.folder)

            def openInterface(ifname):
                fp = self.interfaces[interface] = RawPcapWriter(ifname, linktype=0)
                fp._write_header(None)

            # Try to open input interfaces. Each time, we set a 2 second
            # timeout. If the timeout expires we check if the bmv2 process is
            # not running anymore. If it is, we check if we have exceeded the
            # one minute timeout (exceeding this timeout is very unlikely and
            # could mean the system is very slow for some reason). If one of the
            # 2 conditions above is met, the test is considered a FAILURE.
            start = time.time()
            sw_timeout = 60
            # open input interfaces
            # DANGER -- it is critical that we open these fifos in the same
            # order as bmv2, as otherwise we'll deadlock.  Would be nice if we
            # could open nonblocking.
            for interface in sorted(self.interfaces):
                ifname = self.interfaces[interface]
                while True:
                    try:
                        signal.alarm(2)
                        openInterface(ifname)
                        signal.alarm(0)
                    except TimeoutException:
                        if time.time() - start > sw_timeout:
                            return FAILURE
                        if sw.poll() is not None:
                            return FAILURE
                    else:
                        break

            # at this point we wait until the Thrift server is ready
            # also useful if there are no interfaces
            try:
                signal.alarm(int(sw_timeout + start - time.time()))
                self.check_switch_server_ready(sw, int(thriftPort))
                signal.alarm(0)
            except TimeoutException:
                return FAILURE
            time.sleep(0.1)

            runcli = [FindExe("behavioral-model", "simple_switch_CLI"), "--thrift-port", thriftPort]
            if self.options.verbose:
                print("Running", " ".join(runcli))
            cli = subprocess.Popen(runcli, cwd=self.folder, stdin=subprocess.PIPE)
            self.cli_stdin = cli.stdin
            with open(self.stffile) as i:
                for line in i:
                    line, comment = nextWord(line, "#")
                    self.do_command(line)
            cli.stdin.close()
            for interface, fp in self.interfaces.iteritems():
                fp.close()
            # Give time to the model to execute
            time.sleep(2)
            cli.terminate()
            sw.terminate()
            sw.wait()
            # This only works on Unix: negative returncode is
            # minus the signal number that killed the process.
            if sw.returncode != 0 and sw.returncode != -15:  # 15 is SIGTERM
                reportError("simple_switch died with return code", sw.returncode);
                rv = FAILURE
            elif self.options.verbose:
                print("simple_switch exit code", sw.returncode)
            cli.wait()
            if cli.returncode != 0 and cli.returncode != -15:
                reportError("CLI process failed with exit code", cli.returncode)
                rv = FAILURE
        finally:
            try:
                os.remove("/tmp/bmv2-%d-notifications.ipc" % rand)
            except OSError:
                pass
            concurrent.release(rand)
        if self.options.verbose:
            print("Execution completed")
        return rv